Compare commits

...

1,403 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
Anonymoussaurus
596120a215
Merge pull request #1432 from Universal-Debloater-Alliance/docs/remove-cli-readme
docs(cli): remove README after moving it to the wiki
2026-07-14 11:16:37 +02:00
Anonymoussaurus
d98677c7ca
Merge pull request #1420 from iamanaws/chore/cli-deps-and-errors
fix(cli): avoid duplicate error output
2026-07-12 01:15:09 +02:00
Angel J
469ad5f710
docs(cli): remove README after moving it to the wiki 2026-07-11 08:08:16 -07:00
Angel J
81291e0655
fix(cli): avoid duplicate error output 2026-07-11 07:43:16 -07:00
Angel J
f9e4f141c0
chore(deps): bump tokio to 1.52.3 2026-07-11 07:38:48 -07:00
Angel J
1623d39b55
chore(deps): bump clap to 4.6.1 2026-07-11 07:38:45 -07:00
Anonymoussaurus
258a50cdfe
Merge pull request #1427 from Universal-Debloater-Alliance/refactor/pack_id-android
refactor(core): allow "android" `PackageId`
2026-07-06 10:47:34 +02:00
Rudxain
ded17cf91d
refactor(core): allow "android" PackageId 2026-07-01 19:14:56 -04:00
Anonymoussaurus
b051be8162
Merge pull request #1424 from aaronjmars/security/validate-package-id-in-request-builder
harden: validate package-name charset in request_builder
2026-06-26 15:48:17 +02:00
aeonframework
bd1ed7ea76 harden: validate package-name charset in request_builder
`request_builder` interpolates `package` verbatim into a device-shell
action string. Every current caller reconciles the name against the live
device package list first, so this is safe today — but the safety lives in
the callers, not the sink. Add a local charset guard (Android app-ID set
`[A-Za-z0-9_.]`) so a future caller passing an unreconciled or file-sourced
name can't produce an injectable device-shell command. Rejects nothing
legitimate; fails closed (emits no command) on a malformed name.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 10:54:06 -04:00
Anonymoussaurus
6bb0155c3a
Merge pull request #1416 from W1Z00/main
pkg(com.mi.appfinder): update description
2026-06-17 20:55:23 +02:00
Anonymoussaurus
4773be1f00
Merge pull request #1297 from iamanaws/feature/cli
feat: add CLI and restructure into multi-package workspace
2026-06-17 20:49:43 +02:00
Anonymoussaurus
7d023fadef
Merge pull request #1414 from Forero-0/main
pkg(samsung): add/update packages
2026-06-17 20:49:07 +02:00
Anonymoussaurus
826b159d03
Merge pull request #1413 from strumiv/pkg-motorola-setup-update
pkg(motorola): update com.motorola.setup removal level and description
2026-06-17 20:48:10 +02:00
W1Z00
ddd9b16ced
update desc for com.mi.appfinder 2026-06-17 18:38:00 +08:00
Forero-0
1f561b8d2d Update uad_lists.json 2026-06-16 18:22:28 -05:00
Angel J
02ba6e2cca
refactor: move theme to uad-gui; drop core gui deps; mark PmCommand must-use 2026-06-13 17:21:31 -07:00
Angel J
da7482601e
fix(cli): improve package verification, and output robustness 2026-06-13 17:21:28 -07:00
iamanaws
7dcb7e9315
feat: add CLI and restructure into multi-package workspace
- Add crates/uad-cli for command-line interface
- Extract shared logic into crates/uad-core
- Separate GUI into crates/uad-gui
- Enable code reuse across components
2026-06-13 17:21:27 -07:00
itz8bitstudios
b86c41187c pkg(motorola): update com.motorola.setup removal level and description
- Change removal level from Advanced to Expert
- Update description to emphasize security patch implications
- Clarify that freezing breaks Google Play System Updates (Project Mainline)
- Add clear warning about security patch impact

Closes #1412
2026-06-13 17:06:29 +02:00
Anonymoussaurus
1bb1453257
Merge pull request #1410 from Universal-Debloater-Alliance/chore/keyboard
pkg(aosp): fix typo in AOSP keyboard app description
2026-06-08 00:15:33 +02:00
Angel J
649d0d0bcf
pkg(aosp): fix typo in AOSP keyboard app description 2026-06-04 19:31:58 -07:00
Anonymoussaurus
0e5203f2fa
Merge pull request #1408 from Lost-Entrepreneur439/main
pkg(samsung, bell): add packages from Samsung Galaxy A21
2026-05-31 15:42:37 +02:00
Evelyn Torres
b11ac0bff9 pkg(samsung, bell): Add packages from Samsung Galaxy A21 2026-05-31 08:17:58 -02:30
Ricardo Fernández Serrata
6dea60dfc0
Merge pull request #1407 from Universal-Debloater-Alliance/dependabot/cargo/tar-0.4.46
chore(deps): bump tar from 0.4.45 to 0.4.46
2026-05-30 16:39:44 -04:00
dependabot[bot]
6e02459ee2
chore(deps): bump tar from 0.4.45 to 0.4.46
Bumps [tar](https://github.com/composefs/tar-rs) from 0.4.45 to 0.4.46.
- [Release notes](https://github.com/composefs/tar-rs/releases)
- [Commits](https://github.com/composefs/tar-rs/compare/0.4.45...0.4.46)

---
updated-dependencies:
- dependency-name: tar
  dependency-version: 0.4.46
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-29 21:57:11 +00:00
Anonymoussaurus
5492d39683
Merge pull request #1397 from Lost-Entrepreneur439/main
pkg(insulet): add packes from omnipod dash pdm
2026-05-18 11:27:47 +02:00
Evelyn
fb0dfa8d14
pkg(aosp): Update description for onetimeinitalizer 2026-05-12 17:17:10 -02:30
Anonymoussaurus
96dd6d937e
Merge pull request #1399 from Universal-Debloater-Alliance/g.aosp.wifi.res.ol-update
pkg(com.google.android.wifi.resources.overlay.common): update description
2026-05-11 14:36:35 +02:00
Anonymoussaurus
2739d9b213
Merge pull request #1398 from Universal-Debloater-Alliance/fix-linux-font
fix(gui): use Adwaita on Linux
2026-05-11 14:03:21 +02:00
Rudxain
8b0e15eb9a
pkg: update com.google.android.wifi.resources.overlay.common 2026-05-09 05:17:41 -04:00
Rudxain
51a929009c
docs(gui): explain Adwaita hack 2026-05-09 04:54:02 -04:00
bobbie.w
9108e3d4b4
fix(gui): explicitly request Adwaita Sans font on Linux to prevent Bounding Box clipping from monospace fallback 2026-05-09 04:48:27 -04:00
dependabot[bot]
e0e87e39ea
chore(deps): bump rand from 0.8.5 to 0.8.6 (#1387)
Bumps [rand](https://github.com/rust-random/rand) from 0.8.5 to 0.8.6.
- [Release notes](https://github.com/rust-random/rand/releases)
- [Changelog](https://github.com/rust-random/rand/blob/0.8.6/CHANGELOG.md)
- [Commits](https://github.com/rust-random/rand/compare/0.8.5...0.8.6)

---
updated-dependencies:
- dependency-name: rand
  dependency-version: 0.8.6
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Anonymoussaurus <50231698+AnonymousWP@users.noreply.github.com>
2026-05-09 04:30:51 -04:00
dependabot[bot]
01dd13117c
chore(deps): bump rustls-webpki from 0.103.10 to 0.103.13 (#1383)
Bumps [rustls-webpki](https://github.com/rustls/webpki) from 0.103.10 to 0.103.13.
- [Release notes](https://github.com/rustls/webpki/releases)
- [Commits](https://github.com/rustls/webpki/compare/v/0.103.10...v/0.103.13)

---
updated-dependencies:
- dependency-name: rustls-webpki
  dependency-version: 0.103.13
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Anonymoussaurus <50231698+AnonymousWP@users.noreply.github.com>
2026-05-09 04:08:01 -04:00
Evelyn Torres
c16ee8b379 pkg(insulet): add packes from omnipod dash pdm 2026-05-08 13:18:58 -02:30
Anonymoussaurus
b47675e913
Merge pull request #1347 from Mickmick21/main
pkg(honor) : add packages
2026-05-05 15:39:31 +02:00
Mickmick21
1731d39a2d Update uad_lists.json
Update uad_lists.json

Final ?

Update uad_lists.json

Update uad_lists.json0

Update uad_lists.json

Final commit.

Perfect example of why to check your commits.

pkg(jp.co.omronsoft.iwnnime.ml): change to unsafe

Don't know how to name this.

Try to resolve conflicts

I hate conflicts so much
2026-05-05 14:59:14 +02:00
Anonymoussaurus
dc6d383f58
Merge pull request #1393 from JustArchi/patch-1
pkg(com.motorola.securevault): change removal
2026-05-05 11:49:27 +02:00
Anonymoussaurus
a3de7464d4
Merge pull request #1392 from Raihann22/patch-1
pkg(com.android.providers.contacts): change description
2026-05-05 11:48:29 +02:00
Anonymoussaurus
0415bab6c0
Merge pull request #1375 from nyxSeal/main
pkg: change descriptions and removals
2026-05-05 11:43:44 +02:00
Anonymoussaurus
f788c87daa
Merge branch 'main' into main 2026-05-05 11:40:46 +02:00
Łukasz Domeradzki
20fcc6e7b6
pkg(com.motorola.securevault): Improve description 2026-05-01 14:09:49 +02:00
Łukasz Domeradzki
ede2b02501
pkg(com.motorola.securevault) Move under advanced 2026-05-01 00:09:12 +02:00
Raihan
d6a0d0733e
Update uad_lists.json
Updated the description for the com.android.providers.contacts to include additional information about Bluetooth malfunction on POCO Pad M1.
2026-04-30 15:53:37 +08:00
Anonymoussaurus
1d93422e6f
build: fix error and warnings (#1384)
* build: fix error and warnings

Address clippy suggestions and clean up pattern matching:

- Replace manual sort_by with sort_by_key(|a| a.name.to_lowercase()) for user_package in fetch_packages.
- Add #[allow(clippy::unused_self)] to UadGui::title and UadGui::subscription to silence unused_self warnings.
- Simplify the keyboard event match by destructuring the Character variant directly for clearer pattern matching.
- Add #[allow(clippy::too_many_lines)] to nav_menu to silence the long-function lint.

These are lint and readability-focused changes with no intended behavioral change.

* chore(clippy): add reason

* build(ci): fix formatting
2026-04-29 20:08:56 -04:00
nyxSeal
e7a96d7e0f
docs: update conflicted package description
added both the part where it will drain your battery and where it contains a lot of useful features
2026-04-29 22:22:57 +00:00
nyxSeal
3bc499db42 Merge remote-tracking branch 'upstream/main' 2026-04-29 17:54:25 -04:00
nyxSeal
0a76d615ba
docs: update personal safety app
change from recommended to advanced, plus a bit of info about what this app adds without a google account
2026-04-29 20:49:16 +00:00
Anonymoussaurus
bf3d6ccc59
Merge pull request #1388 from asahi-xd/main
pkg(com.transsion.batterylab): change description
2026-04-29 22:43:19 +02:00
Asahi
01a37e2d33 fixed typo and added personal observations
I have fixed a few typos, and added my personal experiences with this program. I was feeling experimental and tried to use its 'battery saving' features, and ended up completely regretting it.
2026-04-25 00:39:14 +05:30
Anonymoussaurus
8e160ff738
Merge pull request #1382 from JustArchi/patch-1
pkg(com.xiaomi.cameramind): change description and removal
2026-04-22 18:06:42 +02:00
Łukasz Domeradzki
f85c85a592
Merge branch 'main' into patch-1 2026-04-22 18:05:20 +02:00
Anonymoussaurus
7eaff8f810
Merge pull request #1380 from Universal-Debloater-Alliance/opt-image
build(logo): optional `image` dep
2026-04-22 17:31:22 +02:00
Łukasz Domeradzki
acef695f8e
Add camera as dependency to cameramind 2026-04-22 01:38:39 +02:00
Łukasz Domeradzki
3e52ff6ba1
Move com.xiaomi.cameramind under advanced 2026-04-22 01:20:53 +02:00
Leonardo Guerreiro
644b30ae73
Merge pull request #1379 from Forero-0/add-packages
pkg(samsung): add packages
2026-04-13 16:01:08 +01:00
Anonymoussaurus
23cdfafefb
Merge pull request #1367 from reindex-ot/main
pkg(aura): add packages
2026-04-12 16:39:36 +02:00
Rudxain
49250576f3
build(logo): optional image dep 2026-04-11 00:58:55 -04:00
Forero-0
a5d095e140 Update uad_lists.json 2026-04-09 19:02:25 -05:00
Anonymoussaurus
fd94a84a71
Merge pull request #1371 from lawson85/LDplayer-packages
pkg(cyanogemod): add packages
2026-04-06 12:38:21 +02:00
Anonymoussaurus
52f56a42cf
Merge pull request #1374 from Efreak/main
pkg(com.samsung.storyservice): change description
2026-04-06 12:37:33 +02:00
Efreak
6a44fda50a Removal advanced for com.samsung.storyservice 2026-04-05 23:50:09 -07:00
Jacob L
e2c47a7a2d
Fix formatting in uad_lists.json 2026-04-05 15:20:23 +01:00
Re*Index. (ot_inc)
a8ed2ea1ec
Fix typo 2026-04-05 06:58:17 +09:00
nyxSeal
648f5a088f
docs: change description and removal for com.transsion.zahooc and com.transsion.batterylab 2026-04-03 22:52:14 +00:00
nyxSeal
a6865c01a5
docs: change 7 package descriptions and/or removal 2026-04-03 22:38:17 +00:00
Efreak
5b52c2dbe6 disabling com.samsung.storyservice disables samsung edge panels 2026-04-03 15:29:45 -07:00
nyxSeal
2cac0cb2ca
Revert 1ef7a9f and 745f036
Didn't see that the issue was awaiting author response
2026-04-03 21:37:00 +00:00
nyxSeal
1ef7a9f67c
docs: re-add missing description segment 2026-04-03 21:31:48 +00:00
nyxSeal
745f03654c
docs: update description and removal for android.auto_generated_rro_product__ 2026-04-03 21:30:21 +00:00
nyxSeal
06e5dbd2db
docs: update description and removal for com.google.android.apps.camera.services 2026-04-03 21:26:36 +00:00
nyxSeal
26b470d8a2
docs: update com.google.android.settings.intelligence
add comprehensive comparison chart for alternative launchers
2026-04-03 21:24:53 +00:00
nyxSeal
e23a0c9058
docs: update description for com.google.android.apps.nexuslauncher 2026-04-03 21:20:46 +00:00
nyxSeal
f8ccfa686c
docs: update description and removal for com.google.hearing.visualization.accessibility.scribe 2026-04-03 21:18:11 +00:00
nyxSeal
4cec1c0a91
docs: update descriptions and removals for com.google.android.soundpicker and com.google.android.settings.intelligence 2026-04-03 21:12:14 +00:00
Jacob L
8e852266b2
Add Cyanogenmod file manager to uad_lists.json
Added entry for Cyanogenmod file manager with details.
2026-04-02 14:32:33 +01:00
Jacob L
ae3c59cf89
Add android.ext.shared entry to uad_lists.json 2026-04-02 13:42:46 +01:00
Re*Index. (ot_inc)
82adb10fc0
Add Aura from Unity section 2026-03-27 02:13:11 +09:00
Re*Index. (ot_inc)
32360a04b6
Add Aura from Unity srction. 2026-03-27 02:12:24 +09:00
Anonymoussaurus
afe7deb29f
Merge pull request #1356 from Universal-Debloater-Alliance/dependabot/cargo/tar-0.4.45
chore(deps): bump tar from 0.4.44 to 0.4.45
2026-03-26 15:04:24 +01:00
Anonymoussaurus
37eaee257d
Merge pull request #1357 from Universal-Debloater-Alliance/dependabot/cargo/rustls-webpki-0.103.10
chore(deps): bump rustls-webpki from 0.103.8 to 0.103.10
2026-03-26 15:04:11 +01:00
Anonymoussaurus
5a60cfbe53
Merge pull request #1354 from hstsethi/main
pkg(in.gov.uidai.pehchaan): add package
2026-03-26 11:05:29 +01:00
Harshit Sethi
61e1bd29ad
Merge branch 'main' into main 2026-03-26 12:40:47 +05:30
Anonymoussaurus
794fe96910
Merge pull request #1359 from truelockmc/main
pkg(com.samsung.android.timezone.data_R): change description and removal
2026-03-25 20:54:37 +01:00
true_lock
51eb6e0a87
Restored Changes on com.samsung.android.timezone.data_R description 2026-03-25 20:20:50 +01:00
truelockmc
0363d93e89 Merge remote-tracking branch 'upstream/main' 2026-03-25 20:14:54 +01:00
Anonymoussaurus
21da7c0b27
Merge pull request #1355 from nift4/main
pkg(aosp): change removals and descriptions
2026-03-25 19:44:16 +01:00
Anonymoussaurus
9aa03efdd6
Merge pull request #1352 from Forero-0/main
pkg(samsung): add packages
2026-03-25 19:39:40 +01:00
true_lock
d2e81c6629
Update description for Samsung Galaxy A50 bootloop issue 2026-03-21 22:25:52 +01:00
true_lock
8caff5c7fd
fixed data for com.samsung.android.timezone.data_R 2026-03-21 17:36:35 +01:00
dependabot[bot]
2caad7db20
chore(deps): bump rustls-webpki from 0.103.8 to 0.103.10
Bumps [rustls-webpki](https://github.com/rustls/webpki) from 0.103.8 to 0.103.10.
- [Release notes](https://github.com/rustls/webpki/releases)
- [Commits](https://github.com/rustls/webpki/compare/v/0.103.8...v/0.103.10)

---
updated-dependencies:
- dependency-name: rustls-webpki
  dependency-version: 0.103.10
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-21 09:38:03 +00:00
dependabot[bot]
6047737118
chore(deps): bump tar from 0.4.44 to 0.4.45
Bumps [tar](https://github.com/alexcrichton/tar-rs) from 0.4.44 to 0.4.45.
- [Commits](https://github.com/alexcrichton/tar-rs/compare/0.4.44...0.4.45)

---
updated-dependencies:
- dependency-name: tar
  dependency-version: 0.4.45
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-20 18:12:23 +00:00
nift4
c93331e8c8 Some AOSP apps are better left alone 2026-03-20 16:05:54 +01:00
HstSethi
b9216c0120 pkg(in.gov.uidai.pehchaan) Add new Aadhaar app mandated by government to list 2026-03-20 09:31:37 +05:30
Forero-0
9f0e06774f Update uad_lists.json 2026-03-19 12:22:20 -05:00
Forero-0
513688c091 Update uad_lists.json 2026-03-18 22:09:07 -05:00
Anonymoussaurus
758a2639a1
Merge pull request #1348 from wiggleforlife/main
pkg(jp.co.omronsoft.iwnnime.ml): change to unsafe
2026-03-18 20:02:42 +01:00
Cian Ormond
a4f03d1b43
pkg(jp.co.omronsoft.iwnnime.ml): change to unsafe 2026-03-15 19:09:14 -07:00
Anonymoussaurus
da0fdd238c
Merge pull request #1334 from flojo007/main
pkg: change descriptions for soundalive & scpm
2026-03-12 14:10:36 +01:00
flojo007
5590b2f809
Update descriptions and removal recommendations 2026-03-10 19:45:22 +01:00
Ricardo Fernández Serrata
44a041bf74
Merge pull request #1285 from Universal-Debloater-Alliance/dependabot/cargo/time-0.3.47
chore(deps): bump time from 0.3.44 to 0.3.47
2026-03-09 02:25:00 -04:00
flojo007
17e5d07a84
Enhance app descriptions in uad_lists.json
Updated descriptions for Samsung Cloud Platform Manager and SoundAlive apps to include additional notes on uninstallation and potential issues.
2026-03-08 22:02:02 +01:00
Anonymoussaurus
9a6fbbd610
Merge pull request #1324 from Universal-Debloater-Alliance/inputsettings-miui-cam-ring
pkg(xiaomi): Camera Ring dependency
2026-03-08 13:14:42 +01:00
Rudxain
af50b48c68
pkg(xiaomi): Camera Ring dependency 2026-03-01 00:38:44 -04:00
Anonymoussaurus
6286b657ef
Merge pull request #1303 from pm-alonso/patch-1
pkg(com.motorola.systemserver): update description
2026-02-27 21:04:56 +01:00
Anonymoussaurus
6f4a13dbaf
Merge pull request #1310 from 4lphy/patch-1
pkg(com.samsung.android.smartmirroring): change description
2026-02-27 20:47:19 +01:00
Alperen Poyraz
3e4b8d65e9
Uad list update - uninstalling smartmirroring package breaks edge panels feature
Uninstalling this breaks edge panels feature; edge panels won't work and will also crash OneUI Home when trying to switch edge panels on from settings > display. The edge panels package (com.samsung.android.app.cocktailbarservice and com.samsung.android.app.appsedge) doesn't exist on my phone so maybe on newer devices Samsung moved that functionality to this package instead. Tested on Galaxy S25 FE Android 16.
2026-02-25 15:21:06 +03:00
pm-alonso
4fddde5cc9
Please Update uad_lists.json
This updated description will help someone like me to identify the one missing package that breaks Fast Flashlight Gesture (a very useful feature of Motorola phones indeed)
2026-02-23 23:47:20 -03:00
Anonymoussaurus
aa280b042b
Merge pull request #1300 from AstroMeYT/patch-1
pkg(com.sec.android.app.tfunlock): add package
2026-02-22 16:08:44 +01:00
AstroMeYT
718a7d32de
feat(app-description): added com.sec.android.app.tfunlock app description 2026-02-22 08:42:04 -06:00
Anonymoussaurus
a5136a6674
chore(pull-request-templates): add templates (#1283)
* chore(pull-request-template): add templates

Introduce two pull request templates to standardize contributions: .github/pull_request_template/app.md for app-related changes (description, related issues, testing matrix, checklist) and .github/pull_request_template/packages.md for package updates (description, testing, acknowledgements, package validation checklist). These templates help ensure consistent PR metadata and verification steps for maintainers and contributors.

* chore(pull-request-templates): add documentation template

Add .github/pull_request_template/documentation.md to provide a standardized pull request template for documentation updates. The template includes a Description section, Documentation Changes section, and a checklist (link to CONTRIBUTING, clarity, grammar/spelling, link verification, code example testing, and markdown formatting) to improve consistency and quality of doc PRs.

* chore(pull-request-templates): add desktop/window manager fields

Add 'Desktop Environment' and 'Window System/Manager' checklist items to the app PR template to capture more detailed testing environment information. Also adjust the ADB version line indentation to align with the checklist structure.

* chore(pull-request-templates): use absolute URL for contributing guidelines

* chore(pull-request-templates): move files to dedicated folder

* chore(pull-request-template): reword checkbox

Co-authored-by: Angel J <78835633+iamanaws@users.noreply.github.com>

---------

Co-authored-by: Angel J <78835633+iamanaws@users.noreply.github.com>
2026-02-18 10:52:31 -04:00
Anonymoussaurus
04c91de237
Merge pull request #1294 from AlekEagle/main
pkg(com.samsung.android.honeyboard): update description
2026-02-16 15:39:51 +01:00
Anonymoussaurus
36841b4f12
Merge pull request #1265 from Universal-Debloater-Alliance/pkg(oneplus/oppo/realme)-add-packages
pkg(oneplus/oppo/realme): add packages and change descriptions and removals
2026-02-16 15:35:54 +01:00
Anonymoussaurus
03bcdfbfbf
Merge pull request #1299 from Spyder-0/main
pkg(samsung): add/update packages from Samsung Galaxy S7 Edge
2026-02-16 15:35:27 +01:00
Spyder
79f48b76dc
Add/Update packages from Samsung Galaxy S7 Edge
Added new package: com.samsung.widgetapp.yahooedge.news
Updated existing package: com.microsoft.office.powerpoint
2026-02-15 14:54:49 +04:00
Leonardo Guerreiro
5ef4eeac60
Merge pull request #1293 from Lost-Entrepreneur439/main
pkg(samsung): add packages from Samsung Galaxy A20
2026-02-10 22:31:13 +00:00
Anonymoussaurus
a1f29f1f71
pkg(com.oplus.aipaint): add package 2026-02-10 13:16:59 +01:00
Alek Evans
eb3ba6b5a1
pkg(samsung): Update package description for Samsung Keyboard
Added warning for Edge panel clipboard component breaking when removing the com.samsung.android.honeyboard package.
2026-02-09 17:32:11 -09:00
Evelyn Torres
0084a70da5 pkg(samsung): add packages from Samsung Galaxy A20 2026-02-09 18:22:38 -03:30
Cosm
ebec2292ce
Merge pull request #1286 from MiguVT/patch-1
Add LineageOS Browser App details to uad_lists.json
2026-02-08 22:00:57 +00:00
Cosm
3db14bff8f
Merge pull request #1287 from toboil-features/palm-store-addition
Add notice about functionality loss (Palm Store)
2026-02-08 21:59:05 +00:00
Cosm
6e22b26b46
Merge pull request #1292 from NikolaOroz/NikolaOroz/issue1291
pkg(com.apple.atve.androidtv.appletv): add package
2026-02-08 21:57:39 +00:00
N.Oroz
0768731425 pkg(com.apple.atve.androidtv.appletv): add package 2026-02-08 12:20:02 +00:00
toboil-features
22e5afdfce
Add notice about functionality loss 2026-02-06 12:23:24 +00:00
MiguVT
55fafca735
Merge branch 'main' into patch-1 2026-02-06 10:28:32 +01:00
Anonymoussaurus
e6d44912a7 chore(issue-templates): add removal level options to issue templates
Clarify allowed Removal levels in issue templates by adding explicit options (`Recommended`|`Advanced`|`Expert`|`Unsafe`) to the Removal field. Updates .github/ISSUE_TEMPLATE/3-add-new-packages.yml and .github/ISSUE_TEMPLATE/5-update-apps-description-or-recommendation.yml to prompt contributors to use the defined removal categories from the wiki.
2026-02-06 05:07:21 -04:00
Anonymoussaurus
33f15cb6df chore(issue-templates): add checkbox for reading about removals 2026-02-06 05:07:21 -04:00
MiguVT
1c2d5ded76
Add LineageOS Browser App details to uad_lists.json
Added details for LineageOS Browser App
2026-02-05 23:47:46 +01:00
dependabot[bot]
8e7f9e2107
chore(deps): bump time from 0.3.44 to 0.3.47
Bumps [time](https://github.com/time-rs/time) from 0.3.44 to 0.3.47.
- [Release notes](https://github.com/time-rs/time/releases)
- [Changelog](https://github.com/time-rs/time/blob/main/CHANGELOG.md)
- [Commits](https://github.com/time-rs/time/compare/v0.3.44...v0.3.47)

---
updated-dependencies:
- dependency-name: time
  dependency-version: 0.3.47
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-05 18:58:49 +00:00
Cosm
9befa59723
Merge pull request #1281 from Universal-Debloater-Alliance/dependabot/cargo/bytes-1.11.1
chore(deps): bump bytes from 1.11.0 to 1.11.1
2026-02-03 20:17:51 +00:00
dependabot[bot]
70fd5be601
chore(deps): bump bytes from 1.11.0 to 1.11.1
Bumps [bytes](https://github.com/tokio-rs/bytes) from 1.11.0 to 1.11.1.
- [Release notes](https://github.com/tokio-rs/bytes/releases)
- [Changelog](https://github.com/tokio-rs/bytes/blob/master/CHANGELOG.md)
- [Commits](https://github.com/tokio-rs/bytes/compare/v1.11.0...v1.11.1)

---
updated-dependencies:
- dependency-name: bytes
  dependency-version: 1.11.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-03 19:42:49 +00:00
Cosm
1385d5dfb2
Merge pull request #1277 from MintJapan/docomo-pkg
pkg(docomo, samsung, felica): add docomo pkg, update FeliCa pkg
2026-02-02 15:19:19 +00:00
Cosm
351147888c
Merge pull request #1275 from Lost-Entrepreneur439/main
pkg(samsung, bell, hp): add packages from Samsung Galaxy Core LTE
2026-02-02 15:16:39 +00:00
MintJapan
f60c8982a7
pkg(docomo): fix a mistake 2026-02-01 16:28:00 +09:00
MintJapan
d8441bda83
pkg(docomo, samsung, felica): add docomo pkg, update FeliCa pkg
- add lots of docomo package (Only confirmed on SC-53E, more can be found on older devices)
- some fixes to FeliCa pkg
2026-02-01 16:10:23 +09:00
Evelyn Torres
93a71719b0 pkg(samsung, bell, hp): add packages from Samsung Galaxy Core LTE 2026-01-29 00:27:24 -03:30
Anonymoussaurus
21d71f99fc
Merge pull request #1273 from Universal-Debloater-Alliance/docs/add-appmanager-to-friends
docs(readme): add projects of Muntashir Akon to 'Friends' section
2026-01-26 17:32:41 +01:00
Anonymoussaurus
3acd2301e7
docs(readme): add projects of Muntashir Akon to 'Friends' section 2026-01-26 17:25:39 +01:00
Anonymoussaurus
8b7fe2b98a
pkg(oneplus/oppo/realme): change descriptions for OTA packages 2026-01-26 17:06:55 +01:00
Anonymoussaurus
b47f81b641
pkg(com.oplus.trafficmonitor): revert partially removed description 2026-01-25 15:31:43 +01:00
Anonymoussaurus
c6b1f44bc9
pkg(oneplus/oppo/realme): change descriptions and removal 2026-01-25 15:27:32 +01:00
Anonymoussaurus
106058826f
Merge pull request #1268 from Lost-Entrepreneur439/main
pkg(rogers): add packages from Samsung Galaxy S5 Neo
2026-01-25 13:11:42 +01:00
Ivy
7b6182722c pkg(rogers): add packages from Samsung Galaxy S5 Neo 2026-01-24 23:44:29 -03:30
Anonymoussaurus
6562bddfc1
Merge pull request #1267 from Universal-Debloater-Alliance/1263-choreissue-templates-fix-incorrect-link-removal-definitions
chore(issue-templates): add link to removal definitions
2026-01-24 23:45:11 +01:00
Anonymoussaurus
77f5c30410
chore(issue-templates): add link to removal definitions 2026-01-24 23:29:23 +01:00
Anonymoussaurus
651f424029
Merge pull request #1266 from Universal-Debloater-Alliance/1256-docsreadme-add-friendspartners-section-in-readme
docs(readme): add friends section
2026-01-24 18:03:27 +01:00
Anonymoussaurus
7a1ca4f4c2
docs(readme): add friends section 2026-01-24 16:11:06 +01:00
Anonymoussaurus
ea86289346
pkg(oneplus/oppo/realme): change descriptions and removal
Fixes #839
2026-01-24 13:46:33 +01:00
Anonymoussaurus
2f10530701
pkg(com.oplus.audio.effectcenter): change description and removal
I don't really see why "it's so bloated" if it's just an equalizer for Dolby.

Fixes #900
2026-01-24 13:36:22 +01:00
Anonymoussaurus
a0813db165
pkg(com.oppo.usercenter): add package
fixes #1071
2026-01-24 13:28:19 +01:00
Anonymoussaurus
540a123e77
pkg(com.oplus.cosa): change description and removal
Expanded the description for com.oplus.cosa to clarify its role in managing refresh rates for gaming and streaming apps, and changed its removal recommendation from 'Recommended' to 'Advanced'.
2026-01-24 13:26:25 +01:00
Anonymoussaurus
dfe9921aa0
pkg(oneplus/oppo/realme): add new AI-related packages
fixes #1146
2026-01-24 13:20:49 +01:00
Anonymoussaurus
9431c82637
pkg(lg, sprint, google): add packages from LG Nexus 5 (#1262)
* pkg(lg, sprint, google): add packages from LG Nexus 5

* remove stray newlines
2026-01-21 23:23:09 +01:00
Ivy
0154056d5e remove stray newlines 2026-01-21 16:15:37 -03:30
Den1136
9f140a4b23
pkg: add many new packages (#1180)
* Add 13 new packages from Unlisted

* add 1 more package

* Add 2 more packages

* Change descriptions of some packages

* Fix typo

* Change description for 2 packages

Change description for com.miui.miwallpaper and com.google.android.networkstack.tethering. Didn't move them.

* fix 1 package

* Add 8 new packages

* Fix a package

* Add 1 more package

* Add 3 more packages

* Add 2 more packages

* Finalize new packages (30 Packages)

* Remove unnecessary

* One more change

* Finalize edited packages

* Cover issue #1184

* Add package from issue #1197

* Squashed commit of the following:

commit d00dd63d10
Author: Rudxain <76864299+Rudxain@users.noreply.github.com>
Date:   Sun Nov 23 14:31:49 2025 -0400

    docs(README): replace Matrix logo by icon

commit a12d8412f7
Author: Rudxain <76864299+Rudxain@users.noreply.github.com>
Date:   Sun Nov 23 13:56:30 2025 -0400

    replace discord icon by SVG
    also use MD rather than HTML in README

commit 56e267c85d
Author: Rudxain <76864299+Rudxain@users.noreply.github.com>
Date:   Sun Nov 23 13:11:28 2025 -0400

    docs(CONTRIB): improve `CONTRIBUTING`

commit 944a704ee7
Author: Rudxain <76864299+Rudxain@users.noreply.github.com>
Date:   Sun Nov 23 13:11:02 2025 -0400

    docs(README): improve `README`

commit 83f9f43fde
Merge: fca7922 f62edc1
Author: Anonymoussaurus <50231698+AnonymousWP@users.noreply.github.com>
Date:   Tue Dec 9 13:46:31 2025 +0100

    Merge pull request #1188 from zencd/pkg/pocogames

    pkg(xiaomi): add pre-installed Xiaomi Poco games

commit f62edc16e8
Author: zzz <z@z.com>
Date:   Mon Dec 8 19:55:42 2025 +0300

    Add games to the `uad_lists.json`, pre-installed on Xiaomi Poco X7 Pro. I've uninstalled them without any problem.

commit fca7922b3c
Author: Ihor Romanyshyn <ihor.vapor.romanyshyn@gmail.com>
Date:   Tue Dec 9 14:39:05 2025 +0200

    pkg(com.taboola.mip): add package (#1186)

    * Add description for com.taboola.mip (intrusive Taboola lock-screen module)

    * remove redundant empty line

    ---------

    Co-authored-by: Ihor Romanyshyn <iromanyshyn@laptop>
    Co-authored-by: Anonymoussaurus <50231698+AnonymousWP@users.noreply.github.com>

commit 581f5d4d37
Author: aRav3n <24660772+aRav3n@users.noreply.github.com>
Date:   Tue Dec 9 17:21:55 2025 +0530

    Update uad_lists.json (#1178)

    Update descriptions for:
    - com.samsung.android.app.omcagent
    - de.axelspringer.yana.zeropage
    - com.samsung.android.rampart

    Change description for:
    - com.samsung.android.mapsagent

    Add package:
    - com.google.android.apps.aiwallpapers

    Credit: https://xdaforums.com/t/definitive-oneui-guide-tweaks-optimization-privacy-2025.4685716/

    Co-authored-by: Anonymoussaurus <50231698+AnonymousWP@users.noreply.github.com>

commit 539fa098d0
Author: Clippy <227344378+johny579@users.noreply.github.com>
Date:   Tue Dec 9 11:40:00 2025 +0000

    Merge pull request #1175 from johny579/main

    pkg(overlays): change descriptions and removals

commit bca4148fb9
Merge: 1ea4fdc 6b60ca4
Author: Anonymoussaurus <50231698+AnonymousWP@users.noreply.github.com>
Date:   Tue Dec 9 12:11:23 2025 +0100

    Merge branch 'Lost-Entrepreneur439-main'

commit 6b60ca4926
Merge: 1ea4fdc ddde5e6
Author: Anonymoussaurus <50231698+AnonymousWP@users.noreply.github.com>
Date:   Tue Dec 9 12:10:49 2025 +0100

    Merge branch 'main' of github.com:Lost-Entrepreneur439/universal-android-debloater-next-generation into Lost-Entrepreneur439-main

commit 1ea4fdca30
Merge: 9c87b56 69e63a9
Author: Anonymoussaurus <50231698+AnonymousWP@users.noreply.github.com>
Date:   Tue Dec 9 11:29:33 2025 +0100

    Merge pull request #1022 from Universal-Debloater-Alliance/pkg/tcl

    pkg(tcl): add and update many packs

commit ddde5e6811
Author: Ivy <78825510+Lost-Entrepreneur439@users.noreply.github.com>
Date:   Mon Dec 1 22:07:17 2025 -0330

    Chane com.ipsec.service and com.lge.shutdownmonitor to advanced.

commit e6cdca6c22
Merge: 4651fe6 1f71a85
Author: Ivy <78825510+Lost-Entrepreneur439@users.noreply.github.com>
Date:   Mon Dec 1 22:05:31 2025 -0330

    Merge branch 'main' into main

commit 69e63a9a15
Author: Rudxain <76864299+Rudxain@users.noreply.github.com>
Date:   Sat Jul 19 12:10:01 2025 -0400

    pkg(tcl): updates and adds

    mostly Iris/NXTVISION

commit 4651fe6c49
Author: Ivy <78825510+Lost-Entrepreneur439@users.noreply.github.com>
Date:   Fri Nov 21 12:26:02 2025 -0330

     pkg(lg, misc): add packages from LG Stylo 3 Plus

* Squashed commit of the following:

commit d00dd63d10
Author: Rudxain <76864299+Rudxain@users.noreply.github.com>
Date:   Sun Nov 23 14:31:49 2025 -0400

    docs(README): replace Matrix logo by icon

commit a12d8412f7
Author: Rudxain <76864299+Rudxain@users.noreply.github.com>
Date:   Sun Nov 23 13:56:30 2025 -0400

    replace discord icon by SVG
    also use MD rather than HTML in README

commit 56e267c85d
Author: Rudxain <76864299+Rudxain@users.noreply.github.com>
Date:   Sun Nov 23 13:11:28 2025 -0400

    docs(CONTRIB): improve `CONTRIBUTING`

commit 944a704ee7
Author: Rudxain <76864299+Rudxain@users.noreply.github.com>
Date:   Sun Nov 23 13:11:02 2025 -0400

    docs(README): improve `README`

commit 83f9f43fde
Merge: fca7922 f62edc1
Author: Anonymoussaurus <50231698+AnonymousWP@users.noreply.github.com>
Date:   Tue Dec 9 13:46:31 2025 +0100

    Merge pull request #1188 from zencd/pkg/pocogames

    pkg(xiaomi): add pre-installed Xiaomi Poco games

commit f62edc16e8
Author: zzz <z@z.com>
Date:   Mon Dec 8 19:55:42 2025 +0300

    Add games to the `uad_lists.json`, pre-installed on Xiaomi Poco X7 Pro. I've uninstalled them without any problem.

commit fca7922b3c
Author: Ihor Romanyshyn <ihor.vapor.romanyshyn@gmail.com>
Date:   Tue Dec 9 14:39:05 2025 +0200

    pkg(com.taboola.mip): add package (#1186)

    * Add description for com.taboola.mip (intrusive Taboola lock-screen module)

    * remove redundant empty line

    ---------

    Co-authored-by: Ihor Romanyshyn <iromanyshyn@laptop>
    Co-authored-by: Anonymoussaurus <50231698+AnonymousWP@users.noreply.github.com>

commit 581f5d4d37
Author: aRav3n <24660772+aRav3n@users.noreply.github.com>
Date:   Tue Dec 9 17:21:55 2025 +0530

    Update uad_lists.json (#1178)

    Update descriptions for:
    - com.samsung.android.app.omcagent
    - de.axelspringer.yana.zeropage
    - com.samsung.android.rampart

    Change description for:
    - com.samsung.android.mapsagent

    Add package:
    - com.google.android.apps.aiwallpapers

    Credit: https://xdaforums.com/t/definitive-oneui-guide-tweaks-optimization-privacy-2025.4685716/

    Co-authored-by: Anonymoussaurus <50231698+AnonymousWP@users.noreply.github.com>

commit 539fa098d0
Author: Clippy <227344378+johny579@users.noreply.github.com>
Date:   Tue Dec 9 11:40:00 2025 +0000

    Merge pull request #1175 from johny579/main

    pkg(overlays): change descriptions and removals

commit bca4148fb9
Merge: 1ea4fdc 6b60ca4
Author: Anonymoussaurus <50231698+AnonymousWP@users.noreply.github.com>
Date:   Tue Dec 9 12:11:23 2025 +0100

    Merge branch 'Lost-Entrepreneur439-main'

commit 6b60ca4926
Merge: 1ea4fdc ddde5e6
Author: Anonymoussaurus <50231698+AnonymousWP@users.noreply.github.com>
Date:   Tue Dec 9 12:10:49 2025 +0100

    Merge branch 'main' of github.com:Lost-Entrepreneur439/universal-android-debloater-next-generation into Lost-Entrepreneur439-main

commit 1ea4fdca30
Merge: 9c87b56 69e63a9
Author: Anonymoussaurus <50231698+AnonymousWP@users.noreply.github.com>
Date:   Tue Dec 9 11:29:33 2025 +0100

    Merge pull request #1022 from Universal-Debloater-Alliance/pkg/tcl

    pkg(tcl): add and update many packs

commit ddde5e6811
Author: Ivy <78825510+Lost-Entrepreneur439@users.noreply.github.com>
Date:   Mon Dec 1 22:07:17 2025 -0330

    Chane com.ipsec.service and com.lge.shutdownmonitor to advanced.

commit e6cdca6c22
Merge: 4651fe6 1f71a85
Author: Ivy <78825510+Lost-Entrepreneur439@users.noreply.github.com>
Date:   Mon Dec 1 22:05:31 2025 -0330

    Merge branch 'main' into main

commit 69e63a9a15
Author: Rudxain <76864299+Rudxain@users.noreply.github.com>
Date:   Sat Jul 19 12:10:01 2025 -0400

    pkg(tcl): updates and adds

    mostly Iris/NXTVISION

commit 4651fe6c49
Author: Ivy <78825510+Lost-Entrepreneur439@users.noreply.github.com>
Date:   Fri Nov 21 12:26:02 2025 -0330

     pkg(lg, misc): add packages from LG Stylo 3 Plus

* Edit list descs (approval required)

I wanted to change the description of Unsafe long ago

* Add 2 overlays for com.android.wifi.resources

One more package left undocumented but i have to figure out its purpose first

* Add 1 more package

* Add 1 more package; change 2 packages

* Add 1 package, change 2 packages

* Edit list descs (APPROVAL REQUIRED)

* typo

* Add 1 important package

* Add 10 new packages from #1211

* pkg: fix missing comma in JSON

* Update uad_lists.json

* Update .github/ISSUE_TEMPLATE/3-add-new-packages.yml

Co-authored-by: Anonymoussaurus <50231698+AnonymousWP@users.noreply.github.com>

* #1211 package placeholder for simplicity in my next PR (APPROVAL REQUIRED)

* fix attempt

* fix attempt 2

* Fix attempt 3

* Fix attempt 4

* Fix attempt 5

* Test

* Cancel template

* Correct packages for comments

Finally figured it out

* pkg(com.google.android.health.connect.backuprestore): change removal

* pkg(com.google.android.healthconnect.controller): change removal

* pkg(com.android.healthconnect.overlay): change removal

* SarReduce update

* Fix \n

* Delete resources/assets/uad_lists (1).json

* Fix

---------

Co-authored-by: Anonymoussaurus <50231698+AnonymousWP@users.noreply.github.com>
2026-01-21 11:19:23 +01:00
Ivy
e494a45717 pkg(lg, sprint, google): add packages from LG Nexus 5 2026-01-21 05:53:28 -03:30
Frigyes
435c68dca8
Merge pull request #1260 from Universal-Debloater-Alliance/clippy-allow-noop
chore(cargo-clippy): rm no-op lint line
2026-01-20 08:59:23 -08:00
Rudxain
40e5281ee0 chore(cargo-clippy): rm no-op lint line 2026-01-17 10:11:02 -04:00
Cosm
d288860ac8
Merge pull request #1257 from Cosm-gedenke/package/com.coloros.widget.smallweather
pkg(com.coloros.widget.smallweather): add description and change removal
2026-01-15 19:39:31 +01:00
Anonymoussaurus
ee1068ddf8
Merge pull request #1258 from Universal-Debloater-Alliance/1251-cirelease-move-packages-to-bottom-of-release
ci(release): move packages to bottom of release
2026-01-15 16:39:37 +01:00
Anonymoussaurus
0a60b713db
ci(release): move packages to bottom of release 2026-01-15 16:34:09 +01:00
Anonymoussaurus
9ba456884c
Merge pull request #1222 from Universal-Debloater-Alliance/mailmap
chore(git): add `.mailmap`
2026-01-14 19:00:44 +01:00
Anonymoussaurus
00b242368d
Merge pull request #1253 from Cosm-gedenke/changed_minor_uad_list
pkg: change descriptions and removals
2026-01-13 16:16:16 +01:00
ist1114011
99fb08e9d6 whoops 2026-01-13 15:01:38 +00:00
ist1114011
f92b806002 (pkg): fixed some documentation according to previous PR and new findings 2026-01-13 14:57:36 +00:00
Anonymoussaurus
0f857fb92f
Merge pull request #1250 from chu121su12/patch-2
pkg(com.miui.misound): update description
2026-01-12 14:39:33 +01:00
Saya
4eda9c8c1c
Update uad_lists.json 2026-01-12 19:43:47 +08:00
Rudxain
9f5e134d0a chore(git): add .mailmap 2026-01-11 09:04:00 -04:00
Anonymoussaurus
dcaf90396e
Merge pull request #1248 from Universal-Debloater-Alliance/doc-readme-start
docs(readme): link to Getting-started
2026-01-10 20:40:18 +01:00
Anonymoussaurus
c4af1434c0
Merge pull request #1247 from Universal-Debloater-Alliance/pkg-samsung-talkback
pkg(samsung): add TalkBack link
2026-01-10 20:39:38 +01:00
Anonymoussaurus
91e77493ee
Merge pull request #1246 from Universal-Debloater-Alliance/pkg-typos
pkg: fix some typos
2026-01-10 20:38:22 +01:00
Rudxain
9cc69e6a7d pkg(samsung): TalkBack link 2026-01-10 12:02:00 -04:00
Rudxain
ec5a98109d pkg: fix some typos 2026-01-10 12:01:49 -04:00
Rudxain
52eaead284 docs(README): link to Getting-started 2026-01-10 12:00:22 -04:00
Anonymoussaurus
686b41084e
Merge pull request #1245 from Universal-Debloater-Alliance/doc-adb-pack-url
docs: add proper source for package-ID format
2026-01-10 16:01:15 +01:00
Rudxain
0a81642567 docs: add proper source for package-ID format 2026-01-10 07:44:24 -04:00
Ricardo Fernández Serrata
94d8321e2b
Merge pull request #1242 from lawson85/main
Simplify keyboard shortcut code
2026-01-10 06:14:14 -04:00
Jacob L
424ddeb522 Simplify keyboard shortcut code
Ran cargo fmt as well
2026-01-10 09:59:48 +00:00
Jacob L
9f4327aa4b
Merge pull request #1220 from lawson85/Add-keyboard-shortcuts
feat: add keyboard shortcuts
2026-01-09 20:32:29 +01:00
Cosm
b82c71e1c5
Merge pull request #1240 from Cosm-gedenke/chore/rfd
(chore): bump rfd to 0.17.1
2026-01-09 12:06:30 +00:00
Cosm
76e54c63f8
Merge branch 'main' into chore/rfd 2026-01-09 12:02:45 +00:00
ist1114011
ba8e6ee472 (chore): bump rfd to 0.17.1 2026-01-09 11:57:00 +00:00
Anonymoussaurus
b05ebbf603
Merge pull request #1239 from Universal-Debloater-Alliance/fix/windows-application-has-incorrect-title
fix(window): incorrect title of UAD-ng
2026-01-09 12:23:11 +01:00
Anonymoussaurus
6867c56dae
fix(window): incorrect title of UAD-ng
Cause: iced update to 0.14
2026-01-09 11:53:10 +01:00
Anonymoussaurus
2d4789cb68
Merge pull request #1238 from Universal-Debloater-Alliance/1237-docsreadme-remove-line-numbers-referencing-code
docs(readme): remove line numbers
2026-01-09 11:13:42 +01:00
Anonymoussaurus
1dd2fc5ec1
docs(readme): remove line numbers
Because line numbers can change, it's hard to reference, see https://github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation/pull/1231#discussion_r2672430419.
2026-01-09 11:04:31 +01:00
Ricardo Fernández Serrata
38627b716f
Merge pull request #1235 from Universal-Debloater-Alliance/1024-cireleases-mention-that-packages-are-updated-upon-launch-uad-ng
ci(releases): add note about package list updates
2026-01-08 09:58:41 -04:00
Anonymoussaurus
5dd2d52bbb
ci(releases): add note about package list updates
Added a note to the release workflow clarifying that package list updates do not require a new app version, as UAD-ng fetches the latest package definitions on launch if connected to the internet.
2026-01-08 14:00:11 +01:00
Anonymoussaurus
74575c5541
Merge pull request #1234 from Universal-Debloater-Alliance/1018-choreissue-templates-encourage-users-to-create-pr-from-issue-regarding-packages
chore(issue-templates): encourage PRs in issue templates and add checklist items
2026-01-08 12:39:52 +01:00
Anonymoussaurus
fe238d0e2d
Merge pull request #1233 from Universal-Debloater-Alliance/920-docscontributing-clarify-usage-of-issue-labels
docs(contributing): add issue label and changelog section
2026-01-08 12:39:37 +01:00
Anonymoussaurus
634c91d1db
Merge pull request #1231 from Universal-Debloater-Alliance/863-docsreadme-put-note-that-we-do-not-collect-nor-store-any-telemetry
docs(readme): add privacy section
2026-01-08 12:39:15 +01:00
Anonymoussaurus
a2d112392a
chore(issue-templates): encourage PRs in issue templates and add checklist items
Added sections to issue templates encouraging users to submit Pull Requests and linked to the contribution guide. Also introduced new checklist options for users to indicate willingness to submit a PR, aiming to speed up processing of package-related issues and documentation updates.
2026-01-08 12:19:37 +01:00
Anonymoussaurus
841f0ee6b2
docs(contributing): add issue label and changelog section
Expanded CONTRIBUTING.md with a section describing issue labels, their purposes, and how they map to changelog categories. This helps contributors categorize issues and understand how labels affect release notes.
2026-01-08 12:05:38 +01:00
Anonymoussaurus
c598e4cf9b
docs(readme): fix formatting in documentation list
Added a missing newline before the documentation list in README.md for improved readability.
2026-01-08 11:47:54 +01:00
Anonymoussaurus
cbc0496577
docs(readme): add privacy section
Added a new section detailing that UAD-ng does not collect or transmit user data, and specifying the only external connections made are to GitHub for package lists and updates.
2026-01-08 11:46:39 +01:00
Frigyes
050c8c371e
Merge pull request #1230 from Universal-Debloater-Alliance/dependabot/cargo/lru-0.16.3
chore(deps): bump lru from 0.16.2 to 0.16.3
2026-01-08 09:53:45 +00:00
dependabot[bot]
4832da0f97
chore(deps): bump lru from 0.16.2 to 0.16.3
Bumps [lru](https://github.com/jeromefroe/lru-rs) from 0.16.2 to 0.16.3.
- [Changelog](https://github.com/jeromefroe/lru-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/jeromefroe/lru-rs/compare/0.16.2...0.16.3)

---
updated-dependencies:
- dependency-name: lru
  dependency-version: 0.16.3
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-07 20:49:05 +00:00
Anonymoussaurus
0c80fc9392
Merge pull request #1229 from Universal-Debloater-Alliance/chore(ci)/update-macos-runner-versions
build(ci): bump MacOS runner versions
2026-01-07 19:19:29 +01:00
Frigyes Erdosi Szucs
bf57e9804d
chore(ci): change latest to 15 2026-01-07 10:13:51 -08:00
Frigyes Erdosi Szucs
60fb42c5e7
chore(ci): standardize macos capitalization to line up with GH runners 2026-01-07 04:26:12 -08:00
Frigyes Erdosi Szucs
a68e391bb6
chore(c): bumped runner versions 2026-01-07 04:20:52 -08:00
Frigyes
9d147a691e
Merge pull request #1227 from Universal-Debloater-Alliance/chore/prepare-v1.2.0-release
chore(release): bump version to v1.2.0
2026-01-07 12:01:00 +00:00
Frigyes Erdosi Szucs
65a9bf9efe chore: regenerate lockfile 2026-01-06 11:52:22 -08:00
Frigyes Erdosi Szucs
2eff902f69 chore: Bump UAD-ng version in cargo.toml 2026-01-06 11:52:06 -08:00
Frigyes
61c08773bf
Merge pull request #1221 from Cosm-gedenke/main
fix: Fixed shell issues for packages that can't be enabled
2026-01-06 19:46:54 +00:00
ist1114011
67dbb137c9 fixed clippy issues 2026-01-01 16:48:50 +00:00
ist1114011
a3d4412c8a fixed formatting issues 2026-01-01 16:41:22 +00:00
ist1114011
9c29d6c408 fixed formatting issues
rebasing
2026-01-01 16:37:13 +00:00
Cosm
d839546612
Update list.rs
simple fix, should not break
2025-12-31 20:55:13 +00:00
ist1114011
cf74cead29 fixed shell issues for packages that can't be enabled 2025-12-31 20:10:03 +00:00
Anonymoussaurus
3a0529300a
Merge pull request #1218 from Lkaoof/com.huawei.imedia.sws-description-update
pkg(com.huawei.imedia.sws): update description
2025-12-30 12:31:42 +01:00
Lkaoof
6aa8c42487 pkg(com.huawei.imedia.sws): update description 2025-12-30 13:55:25 +03:00
Anonymoussaurus
f7a37df382
Merge pull request #1214 from Universal-Debloater-Alliance/fix/gui-visual-glitch
fix: resize boxes to fit text without visual weirdness
2025-12-28 12:48:40 +01:00
Frigyes Erdosi Szucs
190967fd12 fix formatting 2025-12-27 21:43:07 -08:00
Frigyes Erdosi Szucs
f7ca723c83 Resize boxes to fit text without visual weirdness 2025-12-27 21:41:30 -08:00
Anonymoussaurus
8c77d463d9
Merge pull request #1207 from Universal-Debloater-Alliance/docs/contrib/big
docs(contributing): rules for mass-edits
2025-12-27 19:51:00 +01:00
Rudxain
3fd3fe334e
docs(contrib): elaborate on AI 2025-12-27 14:15:56 -04:00
Ricardo Fernández Serrata
7dec7926d4 docs(contrib): rm clipboard-emoji
Co-authored-by: Anonymoussaurus <50231698+AnonymousWP@users.noreply.github.com>
2025-12-27 14:03:30 -04:00
Anonymoussaurus
d903483f46 docs(contributing): fix markdownlint 2025-12-27 14:03:30 -04:00
Rudxain
929dfba58d docs(contrib): rules for mass-edits 2025-12-27 14:03:30 -04:00
Anonymoussaurus
c90bd4cdd7
Merge pull request #1196 from iamanaws/deps/iced-14
chore(deps): bump iced from 0.13.1 to 0.14.0
2025-12-25 13:08:56 +01:00
angel
a5c18ee295 chore(deps): bump iced from 0.13.1 to 0.14.0 2025-12-21 20:37:19 -08:00
angel
fdca1495f8 refactor(nix): add macOS 2025-12-21 20:37:19 -08:00
Anonymoussaurus
5a8d1faa5a
Merge pull request #1201 from orianodev/patch-1
pkg(miui.systemui.plugin): added warning
2025-12-21 02:54:44 +01:00
Mecatroniq
0d82aa1c11
pkg(miui.systemui.plugin): added warning
Warning for critical UI breakage concerning Redmi devices.
2025-12-18 13:15:10 -05:00
Rudxain
d00dd63d10 docs(README): replace Matrix logo by icon 2025-12-17 03:41:59 -04:00
Rudxain
a12d8412f7 replace discord icon by SVG
also use MD rather than HTML in README
2025-12-17 03:41:59 -04:00
Rudxain
56e267c85d docs(CONTRIB): improve CONTRIBUTING 2025-12-17 03:41:59 -04:00
Rudxain
944a704ee7 docs(README): improve README 2025-12-17 03:41:59 -04:00
Anonymoussaurus
83f9f43fde
Merge pull request #1188 from zencd/pkg/pocogames
pkg(xiaomi): add pre-installed Xiaomi Poco games
2025-12-09 13:46:31 +01:00
zzz
f62edc16e8 Add games to the uad_lists.json, pre-installed on Xiaomi Poco X7 Pro. I've uninstalled them without any problem. 2025-12-09 13:42:16 +01:00
Ihor Romanyshyn
fca7922b3c
pkg(com.taboola.mip): add package (#1186)
* Add description for com.taboola.mip (intrusive Taboola lock-screen module)

* remove redundant empty line

---------

Co-authored-by: Ihor Romanyshyn <iromanyshyn@laptop>
Co-authored-by: Anonymoussaurus <50231698+AnonymousWP@users.noreply.github.com>
2025-12-09 13:39:05 +01:00
aRav3n
581f5d4d37
Update uad_lists.json (#1178)
Update descriptions for:
- com.samsung.android.app.omcagent
- de.axelspringer.yana.zeropage
- com.samsung.android.rampart

Change description for:
- com.samsung.android.mapsagent

Add package:
- com.google.android.apps.aiwallpapers

Credit: https://xdaforums.com/t/definitive-oneui-guide-tweaks-optimization-privacy-2025.4685716/

Co-authored-by: Anonymoussaurus <50231698+AnonymousWP@users.noreply.github.com>
2025-12-09 12:51:55 +01:00
Clippy
539fa098d0
Merge pull request #1175 from johny579/main
pkg(overlays): change descriptions and removals
2025-12-09 12:40:00 +01:00
Anonymoussaurus
bca4148fb9
Merge branch 'Lost-Entrepreneur439-main' 2025-12-09 12:11:23 +01:00
Anonymoussaurus
6b60ca4926
Merge branch 'main' of github.com:Lost-Entrepreneur439/universal-android-debloater-next-generation into Lost-Entrepreneur439-main 2025-12-09 12:10:49 +01:00
Anonymoussaurus
1ea4fdca30
Merge pull request #1022 from Universal-Debloater-Alliance/pkg/tcl
pkg(tcl): add and update many packs
2025-12-09 11:29:33 +01:00
Anonymoussaurus
9c87b56bb3
Merge pull request #1185 from hstsethi/ss
pkg(com.dot.app.sancharsaathi): Add Sanchar Saathi App
2025-12-02 15:26:53 +01:00
Harshit Sethi
5b2258661d
pkg(com.dot.app.sancharsaathi): Add Sanchaar Saathi App 2025-12-02 18:34:31 +05:30
Ivy
ddde5e6811
Chane com.ipsec.service and com.lge.shutdownmonitor to advanced. 2025-12-01 22:07:17 -03:30
Ivy
e6cdca6c22
Merge branch 'main' into main 2025-12-01 22:05:31 -03:30
Ricardo Fernández Serrata
1f71a85071
Merge pull request #1167 from iamanaws/fix/core-hardening
fix(core): add package state verification and cross-user detection
2025-11-27 11:31:24 -04:00
Rudxain
69e63a9a15
pkg(tcl): updates and adds
mostly Iris/NXTVISION
2025-11-25 14:16:56 -04:00
Anonymoussaurus
e73021eb20
Merge pull request #1174 from Scott-Nx/main
pkg(com.xiaomi.finddevice): update description
2025-11-24 18:47:47 +01:00
Scott-Nx
d876382ae7
pkg(com.xiaomi.finddevice): update description 2025-11-22 23:03:30 +07:00
Ivy
4651fe6c49
pkg(lg, misc): add packages from LG Stylo 3 Plus 2025-11-21 12:26:02 -03:30
iamanaws
07ac838964 chore: fix and apply copilot suggestions 2025-11-20 21:46:19 -08:00
iamanaws
7c641bf258 chore(lint): fix clippy warnings 2025-11-20 20:52:31 -08:00
iamanaws
e184121f5f fix: detect and handle cross-user app restoration behavior
- Add cross-user behavior detection for unexpected restoration patterns
- Fix user isolation to prevent operations on unintended users
- Handle uninstall→restore, uninstall→uninstall, and restore→restore cases
- Prevent ping-pong restoration loops from OEM multi-user implementations

Related to #507
2025-11-20 20:52:31 -08:00
iamanaws
88997bdccc fix(adb): prevent crashes from non-UTF8 output
Use lossy UTF-8 conversion in ADB operations and add user-friendly error messages for common OEM failures (Samsung Knox, work profiles, permission errors).

Closes #1005
Merged from #1024

Co-authored-by: simplehima <simplehima@users.noreply.github.com>
2025-11-20 20:52:31 -08:00
iamanaws
7a15e18844 feat(pkg-state): add fallback verification and disable on reinstall
- Verify package state after operations via ADB commands
- Fallback to disable when uninstall fails due to reinstallation
- Fallback to uninstall when disable fails due to re-enabling
- Add UI notifications to inform users of fallback actions
- Remove unused ChangePackageState message variant

Fixes #632
2025-11-20 20:52:31 -08:00
Anonymoussaurus
93a5e56813
pkg(com.aura.oobe.samsung): change description (#1165)
* Enhance AppCloud description with more details

Updated the description for AppCloud in uad_lists.json to include additional information about IronSource and its ownership by Unity, along with app analysis links for reference.

* Add Knox Admin Documentation
2025-11-19 17:37:42 +01:00
iamanaws
ebcaf5e31f fix(backup): continue restoration when packages are missing from device
Skip missing packages with warning instead of failing entire restore process.
Fixes #538
2025-11-18 18:17:18 -08:00
Ricardo Fernández Serrata
dbd33f2cdb
Merge pull request #1064 from iamanaws/iced-13
chore(deps): bump iced from 0.12.0 to 0.13.1
2025-11-18 21:20:02 -04:00
shuvashish76
aee17d7f6a
Add Knox Admin Documentation 2025-11-18 03:39:55 +00:00
shuvashish76
be5e421e81
Enhance AppCloud description with more details
Updated the description for AppCloud in uad_lists.json to include additional information about IronSource and its ownership by Unity, along with app analysis links for reference.
2025-11-18 02:17:01 +00:00
Murilo Bob
553656e5fa
Merge pull request #1158 from Universal-Debloater-Alliance/pkg/blackview
pkg(blackview): add packages
2025-11-17 19:21:11 +01:00
iamanaws
7580105910 chore(lint): solve clippy warnings 2025-11-17 07:24:07 -08:00
iamanaws
4ab886490e chore: replace deprecated adb_shell_command with run_adb_action 2025-11-17 07:15:18 -08:00
iamanaws
369cfaa946 chore(deps): bump iced from 0.12.0 to 0.13.1 2025-11-17 07:13:03 -08:00
iamanaws
ef3803eba5 chore: update flake.nix and flake.lock 2025-11-17 07:02:46 -08:00
Anonymoussaurus
e6d672f817
Update uad_lists.json (#1163)
Add three new packages
2025-11-17 11:26:22 +01:00
Jacob L
6fdda4133e
pkg(com.android.bips): update description (#1155)
* (pkg): default print service, disabling can crash settings app in some cirumstances

Updated the description for the com.android.bips entry to include potential crash issues with the Settings app on specific devices.

* Enhance description for com.android.bips entry

Updated the description for the com.android.bips entry to include information about general device slowness.

* Change BIPS removal label from 'Advanced' to 'Expert'
2025-11-16 23:11:11 +01:00
Den1136
3f0f0684e2
Update uad_lists.json
Add three new packages
2025-11-16 20:51:20 +02:00
foot fondler
e430a6d2da
pkg(androidtv, blackview, bluestacks, google, samsung, unisoc, waydroid): add packages (#1154)
* Android TV; Blackview; Google; and Samsung.

* Update uad_lists.json

* Update uad_lists.json

* Change removal and description

com.android.dialer Advanced → Expert
com.google.android.marvin.talkback Recommended → Advanced
com.android.bluetoothmidiservice Recommended → Advanced

* Update uad_lists.json

* Change Google Speech Services to recommended

* Changed some apps from Recommended to Advanced

com.android.keyguard Recommended → Advanced
com.huawei.ohos.inputmethod Recommended → Advanced
com.samsung.android.net.wifi.wifiguider Recommended → Advanced

* Delete empty line

* Added emulator apps to close #1145

* Update uad_lists.json

* Update uad_lists.json

* Update uad_lists.json

* Update uad_lists.json

* Update uad_lists.json

* 16 apps added

* Update uad_lists.json

* Update uad_lists.json

* Update uad_lists.json

* 4 Japanese carrier apps

* Update uad_lists.json

---------

Co-authored-by: Anonymoussaurus <50231698+AnonymousWP@users.noreply.github.com>
2025-11-16 14:07:24 +01:00
Anonymoussaurus
c197541964
Merge pull request #1157 from Universal-Debloater-Alliance/pkg/xiaomi
pkg(com.xiaomi.aicr): change description and removal
2025-11-16 11:54:10 +01:00
QQ喵
6594a15442
pkg(OnePlus) Make it explicit that com.oplus.athena kills apps (#1156)
* Make it explicit that athena kills apps

* Add a reference link
2025-11-16 11:52:54 +01:00
Anonymoussaurus
d29e927856
Merge pull request #1045 from Universal-Debloater-Alliance/ci/fix-lints-tests
ci: fix lints, disable non-determ tests
2025-11-16 11:39:27 +01:00
Muriilo
337d5e5d96 pkg(Xiaomi) Changing package recommended and description 2025-11-14 17:46:46 -03:00
Anonymoussaurus
f0655e7bd6
Merge pull request #1152 from lawson85/patch-2
pkg(com.aura.oobe.deutsche): add package
2025-11-12 20:23:06 +01:00
Anonymoussaurus
07807130ab
Merge branch 'main' into pr/1152 2025-11-12 20:20:16 +01:00
Anonymoussaurus
6eb6df63b3
Merge pull request #1149 from Universal-Debloater-Alliance/pkg/android
pkg(com.android.angle): change description and removal
2025-11-12 20:15:02 +01:00
Anonymoussaurus
877df6b75e
Merge pull request #1148 from Universal-Debloater-Alliance/pkg/seedvault
pkg(com.stevesoltys.seedvault): change description and removal
2025-11-12 20:09:14 +01:00
Anonymoussaurus
7ccb17c886
pkg(Samsung, Telus): add packages from Galaxy S6 (#1141) 2025-11-12 20:08:08 +01:00
Den1136
51455899dd
pkg(com.android.overlay.circletosearch): add package (#1151)
* Update uad_lists.json

Package addition (com.android.overlay.circletosearch)

* Update uad_lists.json

Edited description
2025-11-12 16:29:25 +01:00
Jacob L
bde5f2af70
Add entry for com.aura.oobe.deutsche in uad_lists.json
Added a new entry for 'com.aura.oobe.deutsche' with details about its list, description and removal recommendation.
2025-11-09 13:58:23 +00:00
Muriilo
7d84630e5c pkg(android angle) Updating the description and changing the removal (#857) 2025-11-07 23:24:25 -03:00
Muriilo
2211d1bf97 pkg(seedvault) Adding a better description and changing the removal tag 2025-11-07 23:00:01 -03:00
Jacob L
9e26136cb3
pkg(overlays): fix package name typo and include adb command for additional information (#1143)
* Enhance overlay descriptions with adb command info

Updated descriptions for various overlays to include adb command for additional information.

* Fix JSON formatting in uad_lists.json

Removing extra "

* Fix formatting of description in uad_lists.json

* Fix parse errors

* Fix more parse errors

Updated descriptions to empty strings for various overlays.

* Trying to fix more parse errors

* Fix JSON formatting
2025-11-05 01:47:29 +01:00
Ivy
621c650d84
pkg(Samsung, Telus): add packages from Galaxy S6 2025-11-02 15:07:48 -03:30
Murilo Bob
141c8df7b4
pkg(Samsung) Add packages (#1133)
Co-authored-by: Anonymoussaurus <50231698+AnonymousWP@users.noreply.github.com>
2025-11-02 16:15:25 +01:00
Ivy
8917703189
Merge pull request #1137 from Lost-Entrepreneur439/main
pkg(samsung): add Bell Canada packages
2025-11-02 16:07:57 +01:00
Anonymoussaurus
a1135dd1ce
Merge pull request #1139 from johny579/main
pkg(google, samsung, unisoc): add packages
2025-11-02 16:00:50 +01:00
foot fondler
8db8bcfcb2
Update uad_lists.json 2025-11-02 13:14:11 +00:00
foot fondler
a5508bb4ec
Update uad_lists.json 2025-11-02 13:12:29 +00:00
Anonymoussaurus
78165eed83
Merge pull request #1134 from Universal-Debloater-Alliance/pkg/Russia
pkg(yandex, vk): add Russian packages
2025-11-02 12:29:17 +01:00
Murilo Bob
58606e31dd
pkg(bigme): add packages (#1129)
Co-authored-by: Anonymoussaurus <50231698+AnonymousWP@users.noreply.github.com>
2025-11-02 12:22:23 +01:00
Jacob L
2f3016537f
pkg(Sony, Qualcomm, AOSP): add packages (#1098)
* Added Sony's unlisted and some other OEM/AOSP to uad_lists.json

Added packages from Sony Xperia X, F5121.
Added some Qualcomm, AOSP packages that were unlisted

* Fix missing bracket and . instead of - uad_lists.json

* Remove extra space in uad_lists.json

Hoping to pass the checks. I get error: Error: Duplicate key 'com.sonyericsson.android.camera' when using online json validator

* Remove duplicateuad_lists.json

I think a duplicate caused an issue

* Removed another duplicate from uad_lists.json

"com.sonyericsson.android.camera"

* Changed oem to Oem uad_lists.json

* Update uad_lists.json

Still trying to fix errors

* Attempt to fix Oem vs oem problem in uad_lists.json

All instances of Oem were estored to oem and then Notepad++ located instances of "list": "oem" and changed to "list": "Oem"

* oem -> OEM uad_lists.json

* Trying again to fix oem

* Update removal labels and descriptions to reflect requested changes
2025-11-02 12:20:04 +01:00
Rudxain
f956c5d452
docs(main): rm redundant doc-comment
this fixes `unused-doc-comments` lint warn
2025-10-31 19:21:45 -04:00
Rudxain
15fcd106f7
ci(cargo-check): deny warns 2025-10-31 19:08:35 -04:00
Rudxain
d74a30b194
Revert "ci(cargo): replace check by clippy"
This reverts commit 38554ca2d7.
2025-10-31 18:46:27 -04:00
Rudxain
ab3081b11d
style(gui/views/list): pkg->p rename, to not shadow pkg 2025-10-31 17:41:09 -04:00
Rudxain
fb131df206
ci(adb): use debug_assert to not trigger panic_in_result_fn 2025-10-31 17:41:09 -04:00
Rudxain
0dc61c825f
refactor(adb): comment-out all running (user) stuff 2025-10-31 17:41:08 -04:00
Rudxain
956d64aa64
refactor(gui/views/list): inline delay_hide_copy_confirmation
fn added in 2ca3e05a8e
2025-10-31 17:41:08 -04:00
Rudxain
6a8ac88b67
ci: disable test_save_changes 2025-10-31 17:41:07 -04:00
Rudxain
7477f02f83
refactor: rm PickList (unused) 2025-10-31 17:41:07 -04:00
Rudxain
3fabd4a8d0
refactor(gui/views/list): mark unused var
lint regression at 26afc32b69
2025-10-31 17:41:07 -04:00
Rudxain
760b21da09
ci(clippy): rm some lints
- `exit` isn't bad for apps, only for libs
- `mem_forget` is rarely a mistake, and is trivial to catch
- `string_to_string` is superseded by `implicit_clone`
- `allow_attributes_without_reason` can be catched by reviewers
2025-10-31 17:41:06 -04:00
Rudxain
d383da804d
ci: cargo clippy --fix; cargo fmt 2025-10-31 17:41:06 -04:00
Rudxain
54308e1c58
ci(adb-sync): un-deprecate adb_shell_command; add warn to docs 2025-10-31 17:41:05 -04:00
Rudxain
2729c72c76
ci: rm config.devices.len() assertion 2025-10-31 17:41:05 -04:00
Muriilo
840bc3d408 pkg(Russian) Adding some Russian packages 2025-10-29 18:21:40 -03:00
foot fondler
4cd0936596
pkg: add bloatware (#1127)
* Added more bloatware

* Added more bloatware

* Add commas

* Update uad_lists.json
2025-10-28 11:08:09 +01:00
MintJapan
9c63d20643
Merge pull request #1126 from MintJapan/FeliCa-pkg
pkg(felica, samsung): adds and update FeliCa & Osaifu-Keitai packages
2025-10-27 11:43:12 +01:00
Anonymoussaurus
b5d655550f
Merge pull request #1121 from Iamanaws/uad_lists
pkg(samsung): add packages
2025-10-26 21:44:39 +01:00
iamanaws
7368c5de47 pkg(samsung, oem): add packages
- pkg(com.samsung.android.knox.*): add Knox enterprise/security packages
- pkg(com.samsung.android.app.vex.scanner): add Document Scanner
- pkg(com.samsung.android.motionphoto.app): add Motion Photo
- pkg(com.samsung.android.wifi.resources.wpa2): add WiFi resources
- pkg(com.monotype.android.font.roboto): add Roboto Font
- pkg(com.val.hardware): add hardware diagnostic tool
2025-10-26 13:41:36 -07:00
Anonymoussaurus
3285ddac66
pkg(nuu): add packages (#913)
* pkg(nuu): add packages

* Apply suggestions from code review
2025-10-26 14:16:41 +01:00
Anonymoussaurus
93280a65aa
Merge pull request #1120 from Universal-Debloater-Alliance/pkg/google
pkg(google): add packages
2025-10-26 12:51:56 +01:00
Anonymoussaurus
f91f135c0e
Merge pull request #1122 from hydrospherics/main
pkg(com.coloros.karaoke): improve description
2025-10-26 12:48:58 +01:00
Anthony L.
aa0f168f9d
corrected `com.coloros.karaoke`'s description. 2025-10-26 07:04:30 +08:00
Anthony L.
fd07a012ca
corrected `com.coloros.karaoke`'s description. 2025-10-26 06:58:17 +08:00
Muriilo
d3e833b14e feat(json documentation) Adding documentation about google apps 2025-10-24 21:34:31 -03:00
Anonymoussaurus
c97ed5dcc1
Merge pull request #1118 from Muriilow/main
pkg(oplus): add com.oplus.studycenter
2025-10-24 17:27:31 +02:00
Murilo Bob
af64ee4a12
Merge branch 'Universal-Debloater-Alliance:main' into main 2025-10-24 12:16:07 -03:00
Muriilo
2ce14936fb feat(json documentation) Adding documentation 2025-10-24 12:14:28 -03:00
Anonymoussaurus
1fcdcaa239
Merge pull request #1117 from Muriilow/main
pkg: add many packages
2025-10-24 16:40:37 +02:00
Muriilo
5e9c1c31d3 feat(json documentation) Adding more packages 2025-10-24 10:21:04 -03:00
Muriilo
b8402242cb feat(json documentation) Adding more documentation 2025-10-24 10:10:58 -03:00
Anonymoussaurus
9b64a5d685
Adding packages preinstalled on Inkbook Devices Closes #811 (#1113) 2025-10-22 11:00:33 +02:00
Muriilo
3932ca66f2 Adding packages preinstalled on Inkbook Devices Closes #811 2025-10-18 18:32:32 -03:00
Ferdinand Saurenbach
bc160c5685
Merge pull request #1105 from FSaurenbach/patch-1
pkg(com.google.android.apps.bard): add package
2025-10-10 10:07:41 +02:00
Anonymoussaurus
9c1ab60eeb
Merge pull request #1086 from d22592/main
pkg(samsung, lge, oplus): add packages
2025-09-29 12:22:39 +02:00
Anonymoussaurus
7f76ba0fdc
Merge pull request #1097 from Lost-Entrepreneur439/main
move com.amazon.venezia to advanced
2025-09-29 10:04:24 +02:00
Ivy
e1c77a4668
move com.amazon.venezia to advanced
Due to it breaking the app drawer on Fire TV, I'd put it as advanced, as it renders the device a lot harder to use unless an alternative launcher is installed.
2025-09-28 21:35:34 -02:30
Ricardo Fernández Serrata
88fc302c05
Merge pull request #1063 from Iamanaws/uad_lists
UPDATED: pkg(samsung, cyrus, google): add packages
2025-09-17 15:10:56 -04:00
Anonymoussaurus
125ef7c820
Merge pull request #1092 from NishchayKQ/patch-1
pkg(com.google.android.overlay.gmsconfig.searchselector): change removal and description
2025-09-15 07:58:36 +02:00
NishchayKQ
f29afcba6c
pkg(com.google.android.overlay.gmsconfig.searchselector): change removal and description 2025-09-15 08:16:04 +05:30
d22592
26c7be73bd
Update uad_lists.json 2025-09-11 22:12:07 +00:00
Ricardo Fernández Serrata
72835c67cd
Merge pull request #1074 from ShahrukhJ/patch-1
pkg(Xiaomi): add App Finder
2025-09-07 18:11:24 -04:00
Name
1852d04284
Update uad_lists.json
UnListed Oem App updated (Xaiomi Poco)
2025-09-01 05:11:18 +00:00
iamanaws
d1db1dd4a4 fix entries Advanced -> Expert, fix formatting 2025-08-23 14:45:45 -07:00
Scharada
ff0566ca42 adding format of Google Pixel 8 missing Packages 2025-08-23 14:28:01 -07:00
Scharada
e87e2aa5c7 adding Google Pixel 8 missing Packages 2025-08-23 14:28:01 -07:00
Scharada
5d6b4b6c2e changes and notify that i have the apk shared 2025-08-23 14:28:01 -07:00
Scharada
d52205ed1c add package com.mediatek.security 2025-08-23 14:28:01 -07:00
Scharada
65e926f458 add package mobile.miki 2025-08-23 14:28:01 -07:00
Scharada
999bb00114 add package com.sec.svoice.lang.* 2025-08-23 14:27:57 -07:00
Ricardo Fernández Serrata
374ecba632
Merge pull request #1049 from Universal-Debloater-Alliance/dependabot/cargo/slab-0.4.11
build(deps): bump slab from 0.4.10 to 0.4.11
2025-08-13 15:33:41 -04:00
dependabot[bot]
9812f7f624
build(deps): bump slab from 0.4.10 to 0.4.11
Bumps [slab](https://github.com/tokio-rs/slab) from 0.4.10 to 0.4.11.
- [Release notes](https://github.com/tokio-rs/slab/releases)
- [Changelog](https://github.com/tokio-rs/slab/blob/master/CHANGELOG.md)
- [Commits](https://github.com/tokio-rs/slab/compare/v0.4.10...v0.4.11)

---
updated-dependencies:
- dependency-name: slab
  dependency-version: 0.4.11
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-13 04:50:08 +00:00
Adhiraj S. Chauhan
826693c79f
Merge pull request #1044 from Universal-Debloater-Alliance/build-script
build(script): use `embed_resource` appropriately
2025-08-10 08:58:16 +05:30
Rudxain
3aa7f56d0c
build: unwrap embed_resource::compile 2025-08-09 20:04:02 -04:00
Rudxain
4eaaca55cf
build: only rerun build.rs if manifest changes 2025-08-09 19:55:38 -04:00
Ricardo Fernández Serrata
fad0ee9630
Merge pull request #1036 from henriquealrs/fix_scroll_crash
fix(list-description-crash): add null action on scroll
2025-08-04 00:43:28 -04:00
Henrique Lustosa
3b7c13dafd Fix lint issue 2025-08-03 19:57:56 -03:00
Henrique Lustosa
26afc32b69 Add null action on scroll to avoid crash 2025-08-03 11:10:09 -03:00
Anonymoussaurus
be03d78ffd
Merge pull request #1033 from alouiadel/feat/add-copy-button
feat(ui): add copy button to copy error messages
2025-08-02 10:03:46 +02:00
Adel Aloui
23ac7ae6ee style: fix formatting issues in list.rs to pass cargo fmt 2025-08-01 15:40:53 +01:00
Adel Aloui
2ca3e05a8e feat(list): add copy confirmation for error messages and improve clipboard handling 2025-08-01 14:17:32 +01:00
Adel Aloui
a20c53a1bc feat(list): add CopyError message and clipboard functionality for error handling 2025-08-01 13:51:38 +01:00
Ricardo Fernández Serrata
4ca22002b5
Merge pull request #1025 from Universal-Debloater-Alliance/refactor/0re
refactor: remove `regex`; parse `UserInfo` from `pm`
2025-07-26 11:04:21 -04:00
Rudxain
207e312741
feat(adb-pm): handle "running" user state 2025-07-22 10:43:55 -04:00
Rudxain
c5799702e2
refactor: rm all regex, and properly parse pm list users 2025-07-22 10:43:55 -04:00
Rudxain
ca0cfd400d
refactor(adb): rm all regex refs in module 2025-07-22 10:43:54 -04:00
Rudxain
5633b077c2
refactor(adb): rm regex dependency from PackageId::new by adding some utils.
and:
- refactor `adb` `version` assertions to call `next` explicitly,
rather than matching on iteration count.
- re-add debug-assertions for `pm list packages`
2025-07-22 10:43:50 -04:00
Ricardo Fernández Serrata
b34492e98c
Merge pull request #949 from Universal-Debloater-Alliance/chore/deps/bump
build(deps): upgrade all dependencies but Iced
2025-07-22 10:42:16 -04:00
Anonymoussaurus
4fc05ab24c
Merge pull request #1019 from Universal-Debloater-Alliance/copilot/fix-1007
pkg(com.google.android.marvin.talkback): add warning about Motorola dynamic volume interference and fix grammar
2025-07-18 17:28:51 +02:00
copilot-swe-agent[bot]
3e57580c1d Update com.google.android.marvin.talkback description with warning and grammar fix
Co-authored-by: AnonymousWP <50231698+AnonymousWP@users.noreply.github.com>
2025-07-18 14:49:33 +00:00
copilot-swe-agent[bot]
474a784df4 Initial plan 2025-07-18 14:39:47 +00:00
Anonymoussaurus
6d93efe94e
Merge pull request #1014 from Scott-Nx/main
pkg(miui, aosp): change description and removal
2025-07-16 00:27:08 +02:00
Scott-Nx
b385b1ea2e
pkg(scope): com.miui.global.packageinstaller 2025-07-15 09:20:37 +07:00
Scott-Nx
df5c051ab5
pkg(scope): com.android.bluetooth 2025-07-15 09:09:58 +07:00
Scott-Nx
ebfbf62e5e
pkg(scope): com.android.emergency 2025-07-15 09:07:15 +07:00
Scott-Nx
161ee6dec2
pkg(scope): com.miui.securitycore 2025-07-15 09:00:13 +07:00
Rudxain
be13905042 chore(deps): upgrade ureq to v3 2025-07-10 10:34:56 +02:00
Rudxain
b778966760 chore(deps): upgrade embed-resource to v3 2025-07-10 10:34:56 +02:00
Rudxain
2069dbf6c3 chore(deps): upgrade dirs to v6 2025-07-10 10:34:56 +02:00
Rudxain
8707cf296e style: cargo fmt 2025-07-10 10:34:56 +02:00
Rudxain
712d61a63c refactor: cargo clippy --fix 2025-07-10 10:34:56 +02:00
Rudxain
a6cbcd9e6e chore(deps): upgrade rfd to 0.15 2025-07-10 10:34:56 +02:00
Rudxain
9d723c6a44 chore(deps): cargo update 2025-07-10 10:34:56 +02:00
Rudxain
94add2dd90 chore(deps): ureq = 2 2025-07-10 10:34:56 +02:00
samuele.ruffino
d471b798c9
feat: make package descriptions selectable and copyable (#1010)
* feat: make package descriptions selectable and copyable

- Replace text widget with text_editor for package descriptions
- Add read-only text_editor that allows text selection and copying
- Implement Clone manually for List struct to handle text_editor::Content
- Add text_editor StyleSheet implementation to match app theme

This improves UX by allowing users to copy package descriptions for
research or sharing purposes while maintaining the same visual appearance.

---------

Co-authored-by: Samuele Domenico Ruffino <sdruffino@it.iliad.com>
2025-07-10 04:04:32 -04:00
Anonymoussaurus
bb1f245bc2
Merge pull request #1011 from Universal-Debloater-Alliance/chore/fix-outdated
chore: fix outdated CI and comments
2025-07-10 09:28:42 +02:00
Rudxain
1fda255b69
ci: rm mold (missed in b86bb3c) 2025-07-10 02:41:46 -04:00
Rudxain
f34e603213
docs: new log-file name
forgot to change this in 2d8d06f
2025-07-10 02:31:13 -04:00
Ricardo Fernández Serrata
4ffdecd123
Merge pull request #1009 from Universal-Debloater-Alliance/build/no-mold
build(cargo): don't use `mold`
2025-07-05 18:16:47 -04:00
Rudxain
7666ef9c85
build(cargo): release opt-lvl 2
I missed this in 45ad468
2025-07-04 15:00:46 -04:00
Rudxain
b86bb3cf69
build(cargo): don't use mold 2025-07-04 14:58:22 -04:00
Ricardo Fernández Serrata
4f25c20072
Merge pull request #1008 from Universal-Debloater-Alliance/build/profile-div
build: split `release` profile into `opt`
2025-07-04 14:17:36 -04:00
Rudxain
45ad468a0e
build: split release profile into opt 2025-07-04 13:51:32 -04:00
Anonymoussaurus
725bfe183c
Merge pull request #1003 from zavocc/coloros-apps-update
pkg(com.coloros.wifibackuprestore): change removal and description
2025-06-28 00:48:37 +08:00
WMCB Tech (marcusz)
d3331b4d45
Update com.oplus.wifibackuprestore description and its removal type 2025-06-27 20:10:52 +08:00
WMCB Tech (marcusz)
11ee8ba214
com.coloros.wifibackuprestore: Change category type to advanced as this can lose the ability to save and restore access points. 2025-06-24 14:46:48 +08:00
Anonymoussaurus
0b37fac065
Merge pull request #1000 from prirai/patch-1
pkg(com.transsion.applock): change description and removal
2025-06-23 12:27:46 +08:00
Priyanshu Kumar Rai
85068a3181
Update uad_lists.json
Removal of this package broke recents for me. Only after installing it back did my recents work. I double checked. Also checked the logcat that indeed applock is linked to the recents as a provider.
2025-06-21 14:15:01 +05:30
Scott
fbe42ef1b2
Merge pull request #997 from Scott-Nx/main
pkg(mediatek): update descriptions
2025-06-19 09:32:54 +08:00
Anonymoussaurus
c7901cbcd0
Merge pull request #995 from NishchayKQ/main
pkg(com.google.android.tungsten.setupwraith): change removal and description
2025-06-17 10:15:12 +08:00
NishchayKQ
b3b195a7e1
pkg(scope): com.google.android.tungsten.setupwraith 2025-06-16 21:11:30 +05:30
Anonymoussaurus
01be1f5e0f
Merge pull request #990 from Universal-Debloater-Alliance/pkg/media-store
pkg(media-storage): add info about indexing/caching
2025-06-11 14:56:49 +08:00
Rudxain
ddf454f885
pkg(media-storage): add info about indexing 2025-06-11 01:34:24 -04:00
Anonymoussaurus
e9a17409dd
pkg(com.motorola.livewallpaper3.prebuilt.*): add Motorola Prebuilt themes
Motorola Prebuilt themes
2025-06-10 14:01:27 +08:00
trustytrojan
6f9e70b647
feat(gui/list): allow searching in descriptions (#977)
Search by description as well as by name

---------

Co-authored-by: Rudxain <76864299+Rudxain@users.noreply.github.com>
2025-06-08 16:12:02 -04:00
Harshit Sethi
ade70a121a
pkg(com.android.avatarpicker): add description of Avatar Picker package (#976)
* pkg(com.android.avatarpicker): Add description of Avatar Picker package

* Fix a minor syntax erorr in json
2025-06-08 17:41:12 +08:00
Sharun
d857bef9b6
fix(crash): index out of bounds exception (#972)
* fix: index out of bounds exception

* cargo fmt

* refactor using get()

* fmt

* potential fix for checkboxes
2025-06-06 10:33:30 +08:00
Anonymoussaurus
8a5a3b7f8f
Merge pull request #984 from Universal-Debloater-Alliance/schbrns/issue929
pkg(scope): com.google.android.safetycenter.resources
2025-06-06 09:14:37 +08:00
Anonymoussaurus
96e5af27f6
Merge pull request #983 from Universal-Debloater-Alliance/schbrns/issue800
pkg(scope): `com.sec.android.app.hwmoduletest` breaks after removing `com.samsung.android.providers.factory` on Samsung Galaxy phones
2025-06-06 09:12:46 +08:00
Anonymoussaurus
a1541b533a
Merge pull request #982 from Universal-Debloater-Alliance/schbrns/issue963
pkg(scope): Remove fearmongering description of com.samsung.android.dqagent
2025-06-06 09:11:10 +08:00
Anonymoussaurus
c0a1f78075
Merge pull request #981 from Universal-Debloater-Alliance/schbrns/issue973
pkg(scope): com.android.apps.turbo - battery settings crash
2025-06-06 09:10:19 +08:00
Anonymoussaurus
ad29532caf
Merge pull request #980 from Universal-Debloater-Alliance/schbrns/issue975
pkg(scope): com.samsung.android.providers.trash Samsung Voice Recorder Crash
2025-06-06 09:09:36 +08:00
Anonymoussaurus
99a5cf8805
Merge pull request #979 from Universal-Debloater-Alliance/schbrns/issue969
pkg(com.oem.euiccpartnerapp): breaks sim manager Moto G 5G 2024
2025-06-06 09:08:27 +08:00
Anonymoussaurus
3a24739a2f
Merge pull request #978 from Universal-Debloater-Alliance/schbrns/issue792
pkg(scope): Issues with SIM Manager, Package Removal, and Performance
2025-06-06 09:07:16 +08:00
schbrns
ffbbe27856 pkg(scope): com.google.android.safetycenter.resources
Fixes #929
2025-06-05 01:37:30 -04:00
schbrns
6f278a6c3a pkg(scope): com.sec.android.app.hwmoduletest breaks after removing com.samsung.android.providers.factory on Samsung Galaxy phones
Fixes #800
2025-06-05 01:33:31 -04:00
schbrns
2a146a1c99 pkg(scope): Remove fearmongering description of com.samsung.android.dqagent
Fixes #963
2025-06-05 01:31:56 -04:00
schbrns
263905b71a pkg(scope): com.android.apps.turbo - battery settings crash
Fixes #973
2025-06-05 01:23:47 -04:00
schbrns
ae1f2931bd pkg(scope): com.samsung.android.providers.trash Samsung Voice Recorder Crash
Fixes #975
2025-06-05 01:21:32 -04:00
schbrns
758e6bcbf1 pkg(com.oem.euiccpartnerapp): breaks sim manager Moto G 5G 2024
Fixes #969
2025-06-05 01:12:54 -04:00
schbrns
10bdbd30cb pkg(scope): Issues with SIM Manager, Package Removal, and Performance
Fixes #792
Fixes #711
2025-06-05 01:08:48 -04:00
Anonymoussaurus
a04104630e
Merge pull request #940 from Universal-Debloater-Alliance/refactor/backup
refactor: `list_available_backup_user` and `CommandType`->`PackageInfo`
2025-05-23 00:27:18 +08:00
Rudxain
59854c4c7c
perf: minor opt (runtime and compile-time) 2025-05-14 23:05:31 -04:00
Rudxain
c0a876da83
refactor: replace CommandType by PackageInfo
https://github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation/issues/760
2025-05-14 23:05:30 -04:00
Rudxain
17a48aae02
style: cargo clippy --fix 2025-05-14 23:05:30 -04:00
Rudxain
a7fd492f5a
refactor(save): more idiomatic list_available_backup_user 2025-05-14 23:05:30 -04:00
Anonymoussaurus
c2614ac892
Merge pull request #966 from antgustech/fix/update-description-oplustrafficmonitor
pkg(com.oplus.trafficmonitor): update description and removal
2025-05-15 09:57:58 +08:00
Adhiraj S. Chauhan
d651a73928
Merge pull request #965 from Lemminkyinen/fix/typos
fix(sync): minor fixes
2025-05-14 23:33:29 +05:30
Antong
5f0c689c95 updated description and removal for com.oplus.trafficmonitor 2025-05-14 15:17:40 +02:00
Anonymoussaurus
6302fbb50b
Merge pull request #964 from AntoninoScordino/main
pkg(com.google.android.pixel.setupwizard): change description and removal
2025-05-14 11:31:01 +08:00
Jarmo Tenhunen
c177fdaac6
fix(sync): remove unnecessary semicolon 2025-05-13 20:47:41 +03:00
Jarmo Tenhunen
cd068e2e47
fix(sync): correct logging typo 2025-05-13 20:46:55 +03:00
Antonino Scordino
07e1c2ea83 pkg(com.google.android.pixel.setupwizard): warn about GPSU breakage
Change-Id: I04c877fa615300bfcd8b024ab030db250084b258
2025-05-13 19:45:10 +02:00
StreetWayfarer
85440777a3
Update uad_lists.json for additional apps
Motorola Prebuilt themes
2025-05-03 02:36:58 +03:00
Anonymoussaurus
25e0ac0cfd
Merge pull request #935 from Universal-Debloater-Alliance/feat/1log
feat(log): single log-file (`const` name)
2025-04-30 12:18:07 +02:00
Rudxain
2d8d06fc3d
feat(log): single log-file (const name) 2025-04-29 18:20:19 -04:00
Anonymoussaurus
1d70755766
Merge pull request #953 from Universal-Debloater-Alliance/ci/cargo-clippy
ci(cargo): improve linting
2025-04-29 21:21:55 +02:00
Rudxain
5c5499bc6b
ci(clippy): deny default warnings
but keep `style` as `warn`
2025-04-29 14:39:45 -04:00
Rudxain
38554ca2d7
ci(cargo): replace check by clippy 2025-04-29 14:28:06 -04:00
Rudxain
ce341df6c3
ci(cargo): rm --all flag 2025-04-29 13:43:57 -04:00
Adhiraj S. Chauhan
1890a214e8
Merge pull request #918 from Universal-Debloater-Alliance/bug/about/panic-adb-version#917
fix(views:about): default text for `adb version`
2025-04-29 12:16:04 +05:30
schbrns
7d3a9947d2
pkg(oem): update descriptions and change removal status for dependencies related to Private space on Pixel devices (#944)
* pkg(oem): update descriptions and change removal status for dependencies related to Private space on Pixel devices

* Update uad_lists.json

Resolve merge conflict.

* Update uad_lists.json
2025-04-27 14:09:02 +02:00
schbrns
a5fb797f9e
Merge pull request #945 from schbrns/schbrns/issue688
pkg(com.android.global): update description and removal behaviour
2025-04-25 13:04:28 +02:00
Anonymoussaurus
19f7ce8187
Merge pull request #946 from AntoninoScordino/main
pkg(com.android.role.notes.enabled): add warning regarding Developer Options
2025-04-24 15:12:02 +02:00
Antonino Scordino
f7e15e9c80 pkg(com.android.role.notes.enabled): add warning regarding Developer Options
Change-Id: Ifbbaa8f3486129dbed464c5818b812ff8259764b
2025-04-24 14:59:04 +02:00
Anonymoussaurus
979df43032
Merge pull request #943 from schbrns/942-pkgscope-comcnnmobileandroidphoneedgepanel
pkg(cnn): remove duplicate
2025-04-23 22:01:39 +02:00
schbrns
830e6883bd pkg(onyx): format JSON 2025-04-23 15:58:35 -04:00
schbrns
cc49ce3c63 pkg(cnn): update edge panel entry and remove outdated parental control description 2025-04-23 15:54:37 -04:00
Anonymoussaurus
3e32074267
Merge pull request #932 from scxtt-nc/main
pkg(com.android.chrome): update description for clarity on functionality
2025-04-14 10:07:15 +02:00
Nathawat
5f2deaa64c
pkg(com.android.chrome): update description to clarify functionality and dependencies 2025-04-14 08:39:01 +07:00
Rudxain
e20b9aef72
fix(views:about): default text for adb version failure
regression introduced here:
3cc2f1d004
2025-03-27 18:46:08 -04:00
Rudxain
6cb12ea91b
perf(ADB): defer version parsing to caller
Change the method signature to
allow the consumer to decide when/if and how to parse the `stdout`
2025-03-27 18:41:40 -04:00
Cameron Jackson
246c2208b0
pkg(miui.systemui.plugin): improve description (#759)
* Reworded as HyperOS devices are now more popular, and losing Quick Settings is more relevant than gaining AOSP volume style.

* Updated to recommended wording

* pkg(miui.systemui.plugin): apply suggestions from code review

---------

Co-authored-by: Anonymoussaurus <50231698+AnonymousWP@users.noreply.github.com>
2025-03-22 11:58:28 +01:00
YoshiiShell
59493b5f9e
pkg(samsung): add packages (#743)
* Packages

* fixes

* fix numba 2

* a

* pkg(samsung): fix formatting and change removals

---------

Co-authored-by: Anonymoussaurus <50231698+AnonymousWP@users.noreply.github.com>
2025-03-22 11:50:39 +01:00
Anonymoussaurus
f0ca2dfe7f
Merge pull request #877 from Universal-Debloater-Alliance/836-pkgscope-comandroidunisoctelephonyserver
pkg(com.android.unisoc.telephony.server): change description and removal
2025-03-18 10:07:14 +01:00
Anonymoussaurus
9bf8c1abe3
pkg(com.android.server.deviceconfig.resources): add package (#826)
* pkg(com.android.server.deviceconfig.resources): add package

* pkg(com.android.server.deviceconfig.resources): apply suggestion from code review

* pkg(com.android.server.deviceconfig.resources): apply suggestion from code review
2025-03-18 10:06:51 +01:00
Anonymoussaurus
6ebd13aaf5
Merge pull request #822 from Universal-Debloater-Alliance/716-update-description-of-pkgcomandroidincallui
pkg(com.android.incallui): change description and removal
2025-03-18 10:06:01 +01:00
Ricardo Fernández Serrata
d562efe813
Merge pull request #868 from Universal-Debloater-Alliance/pkg/gms
pkg: improve GMS and WA desc
2025-03-17 19:18:12 -04:00
Anonymoussaurus
173c600f0b
Merge pull request #898 from Universal-Debloater-Alliance/hotfix/conditional-condition-panic
fix: fix all `cfg` shenanigans
2025-03-10 21:53:04 +01:00
Rudxain
7506112daf
fix: refactor and sync self-update cfgs
regressed by: 3cc2f1d004
2025-03-10 16:22:51 -04:00
Rudxain
f6bf0048b5
hotfix(adb): use actual cfg instead of debug_assert
fixes regression introduced by this commit:
db719e0cb4
2025-03-10 15:56:30 -04:00
Frigyes
9fbf8cfdd4
Merge pull request #897 from Universal-Debloater-Alliance/release/bump-version-to-1.1.2
chore(release): bump version to 1.1.2
2025-03-10 19:27:39 +00:00
Anonymoussaurus
c649a261b3
docs(release): mention that we need to update Cargo.lock 2025-03-10 20:25:58 +01:00
Anonymoussaurus
1dbaeb56d8
chore(release): bump version to 1.1.2 2025-03-10 20:25:43 +01:00
Ricardo Fernández Serrata
f9f8212562
Merge pull request #894 from Universal-Debloater-Alliance/feat/gui/adb-v__893
feat(GUI:view:about): show `adb version`
2025-03-10 15:16:56 -04:00
Rudxain
adeed4c1a5
docs(adb): mv alloc comment 2025-03-10 14:44:51 -04:00
Rudxain
db719e0cb4
test(ADB): verify adb version format with debug_assertions 2025-03-10 14:37:27 -04:00
Rudxain
2e1e364e29
docs(ADB): specify txt for version sample 2025-03-10 14:09:04 -04:00
Rudxain
9dac3a6934
docs(ADB): explain expected version format 2025-03-10 13:52:29 -04:00
Ricardo Fernández Serrata
be39579115
Merge pull request #895 from Universal-Debloater-Alliance/fix/selfupdate-apple-arch
hotfix(self-update): differentiate between Intel and Apple Silicon on MacOS and update Windows binary name
2025-03-10 13:38:49 -04:00
Frigyes Erdosi-Szucs
b22d38ca07 fix(selfupdate): Update windows binary name 2025-03-10 09:53:18 -07:00
Frigyes Erdosi-Szucs
657ebcb16e fix(autoupdate): Add aarch64 to apple silicon target 2025-03-10 09:35:03 -07:00
Frigyes Erdosi-Szucs
7e0a9f3b64 fix(autoupdate): Add x86 to intel target as well 2025-03-10 09:31:53 -07:00
Frigyes Erdosi-Szucs
340d49a99f style: format with fmt 2025-03-10 09:22:36 -07:00
Frigyes Erdosi-Szucs
3b3690316b fix(selfupdate): Differentiate between intel and apple silicon on macos 2025-03-10 09:18:35 -07:00
Rudxain
780c0d7a6d
fix(ADB): forgot to rm all quotes from logger
continuation of commit:
1d657e899e
2025-03-10 12:09:42 -04:00
Rudxain
3cc2f1d004
feat(view:about): show ADB version in GUI 2025-03-10 11:52:14 -04:00
Rudxain
9508bd8aa8
chore(ADB): add version method to internal ADB API 2025-03-10 11:50:34 -04:00
Ricardo Fernández Serrata
87b5a9a924
Merge pull request #890 from Universal-Debloater-Alliance/release/bump-uad-ng-version
chore(release): bump version to 1.1.1
2025-03-09 16:31:58 -04:00
Anonymoussaurus
44b1b92f47
chore(release): update UAD-ng version in Cargo.lock to 1.1.1 2025-03-09 19:09:10 +01:00
Frigyes
f7e10a6c4c
Merge pull request #889 from Universal-Debloater-Alliance/886-docsrelease-create-release-file-and-change-way-of-working-regarding-releases-dependencies
docs(release): add development process header
2025-03-09 17:50:58 +00:00
Anonymoussaurus
be869dace6
chore(release): bump version to 1.1.1 2025-03-09 13:42:30 +01:00
Anonymoussaurus
3c25c88109
docs(release): only mention UAD-ng version 2025-03-09 13:39:08 +01:00
Anonymoussaurus
0c86e71b06
docs(release): add development process header 2025-03-09 13:26:20 +01:00
Anonymoussaurus
68a89d2473
docs(release): move part of contributing to release file 2025-03-09 13:26:09 +01:00
Adhiraj S. Chauhan
90544ac77b
Merge pull request #883 from Universal-Debloater-Alliance/859-choreissue-template-introduce-feature-template-for-cicd
chore(issue-template): add CI issue template
2025-03-08 19:45:04 +00:00
Ricardo Fernández Serrata
8ab29be4f6
Merge pull request #885 from Universal-Debloater-Alliance/no-con_no-err
log: `error`->`warn`, if no device found
2025-03-08 14:11:20 -04:00
Rudxain
7bffe4c303
log error->warn, if no device found 2025-03-08 13:55:21 -04:00
Anonymoussaurus
4338731dd8
chore(issue-template): apply suggestions from code review 2025-03-08 18:29:25 +01:00
Anonymoussaurus
66102f9720
Merge pull request #881 from Universal-Debloater-Alliance/dependabot/cargo/ring-0.17.13
build(deps): bump ring from 0.17.8 to 0.17.13
2025-03-08 17:06:10 +01:00
Anonymoussaurus
f7d77819c1
ci(changelog): add and rename titles 2025-03-08 14:16:32 +01:00
Anonymoussaurus
aa6bd2417a
chore(issue-template): add CI issue template 2025-03-08 14:06:21 +01:00
Anonymoussaurus
cf03839ac7
chore(release): rename testing to ci 2025-03-08 14:06:08 +01:00
dependabot[bot]
96d4fa6577
build(deps): bump ring from 0.17.8 to 0.17.13
Bumps [ring](https://github.com/briansmith/ring) from 0.17.8 to 0.17.13.
- [Changelog](https://github.com/briansmith/ring/blob/main/RELEASES.md)
- [Commits](https://github.com/briansmith/ring/commits)

---
updated-dependencies:
- dependency-name: ring
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-07 17:03:49 +00:00
Anonymoussaurus
c9a8a0bbf5
Merge pull request #880 from Universal-Debloater-Alliance/ci/mute-dupe-lint
refactor(lint): fix/silence some lints
2025-03-07 08:02:55 +01:00
Rudxain
161f816093
docs(adb): improve list_packages_sys doc 2025-03-06 15:24:53 -04:00
Rudxain
1d657e899e
feat(adb): rm quotes from logged args 2025-03-06 15:16:22 -04:00
Rudxain
d3c0ae26c5
perf(adb): PackageId: String -> Box<str> 2025-03-06 15:12:32 -04:00
Rudxain
fdc220febc
chore: fix/mute more lints; rm useless "TODO"s 2025-03-06 03:15:18 -04:00
Rudxain
045d956f40
refactor(sync): merge match arms 2025-03-06 02:54:26 -04:00
Rudxain
ce84dedd29
docs(adb): add blank lines to break list continuations 2025-03-06 02:44:30 -04:00
Rudxain
6743b4d4af
refactor: rm dead code, and fix some lints 2025-03-06 02:40:06 -04:00
Rudxain
630cebd4cf
chore(gui/views/list): silence some lints 2025-03-06 02:16:33 -04:00
Rudxain
499823aa65 refactor(utils): match instead of cfg in open_url 2025-03-06 02:16:13 -04:00
Rudxain
b8abd7d27a docs(utils): doubt about Command::output encoding on Windows 2025-03-06 02:16:13 -04:00
Rudxain
d10e4dcc3a perf(utils): 1 fmt in generate_backup_name 2025-03-06 02:16:13 -04:00
Rudxain
d0f190bf2a docs(lint): add reason for generate_backup_name to take ownership 2025-03-06 02:16:13 -04:00
Rudxain
b71608a95f ci(lint): enable clippy::unwrap_used only for some modules 2025-03-06 02:16:13 -04:00
Rudxain
5a682e2889 refactor: cargo clippy --fix 2025-03-06 02:16:13 -04:00
Rudxain
135b1e8615 ci(lint): allow unsafe_code 2025-03-06 02:16:13 -04:00
Ricardo Fernández Serrata
237d944536
Merge pull request #879 from Universal-Debloater-Alliance/hotfix/ls-users
hotfix(sync:users): revert UID parsing
2025-03-06 02:13:46 -04:00
Ricardo Fernández Serrata
4811873f5c
Merge branch 'main' into hotfix/ls-users 2025-03-05 21:29:57 -04:00
Rudxain
132d7f2dee
hotfix(sync:users): revert UID parsing
partially reverts commit:
77a52be830
2025-03-05 21:18:05 -04:00
Anonymoussaurus
90e5af9089
Merge pull request #864 from Universal-Debloater-Alliance/build/rust-2024
build(rust-edition): migrate to Rust 2024
2025-03-05 20:28:44 +01:00
Anonymoussaurus
8aede76b86
pkg(com.unisoc.phone): change description 2025-03-01 16:40:35 +01:00
Anonymoussaurus
601fe1f36f
pkg(com.android.unisoc.telephony.server): change description and removal 2025-03-01 16:38:13 +01:00
Rudxain
fdfcfe8c9a
pkg: mention WhatsApp dependency on GMS 2025-02-23 15:02:15 -04:00
Rudxain
63c8a72061
pkg(Google): improve GMS description 2025-02-23 14:57:30 -04:00
Rudxain
14ed2dd284
style: cargo fmt 2025-02-22 13:28:20 -04:00
Rudxain
607475ff24
build(rust-edition): cargo fix --edition & update Cargo.toml 2025-02-22 13:28:04 -04:00
Ricardo Fernández Serrata
1d296b3728
Merge pull request #858 from user583953/main
fix: use advanced text shaping to prevent text being rendered as squares with certain fonts or CJK characters
2025-02-22 09:31:07 -04:00
189024609
ab1edfc0d7 refactor: use Formatter::write_str instead of write! macro 2025-02-22 12:18:51 +01:00
189024609
6dc8da102b refactor: use Into<Cow<'a, str>' in text widget and change consumers accordingly 2025-02-21 22:43:02 +01:00
189024609
7bebbc9019 build: simplify disallowed-* message 2025-02-21 21:49:51 +01:00
user583953
498b42540c
Merge branch 'Universal-Debloater-Alliance:main' into main 2025-02-21 21:47:00 +01:00
Anonymoussaurus
3d580bc6c5
Merge pull request #854 from Universal-Debloater-Alliance/795-buildci-version-os-of-runners
build(ci): version-pin OS of runners
2025-02-20 09:09:00 +01:00
Anonymoussaurus
3dec08bee0
Merge pull request #852 from Universal-Debloater-Alliance/hotfix/rm-dbg-pack-validation
fix: disable debug validation of pack-IDs
2025-02-19 19:57:01 +01:00
189024609
1ec58c9df4 build: enforce usage of crate::gui::widget::text via clippy's disallowed-{types, methods} lints 2025-02-19 17:13:25 +01:00
189024609
3362e52382 refactor: replace all usages of iced::widget::{Text, text} with crate::gui::widget::text 2025-02-19 17:11:37 +01:00
189024609
a1908e8c84 feat: add [crate::gui::widgets::text] function to create text with advanced shaping by default 2025-02-19 17:10:27 +01:00
Anonymoussaurus
60c89c887c
build(ci): upgrade GitHub release Action to v2 2025-02-19 00:12:10 +01:00
Anonymoussaurus
13bab7f0c4
build(ci): version-pin OS of runners 2025-02-19 00:11:31 +01:00
user583953
fc9a771b85
fix: force wgpu to use dedicated/discrete graphics-card, to avoid Vulkan issues (#850)
* feat: force wgpu/iced to use gl backend by setting WGPU_BACKEND env var in main()

* feat: force wgpu/iced to use discrete gpu to prevent crashes on multi gpu setups
2025-02-18 23:58:37 +01:00
Rudxain
98077cf5ac
hotfix: disable debug validation of pack-IDs 2025-02-18 11:13:40 -04:00
Anonymoussaurus
52b78a99b4
pkg(com.fintech.life): change description (#835)
* pkg(com.fintech.life): change description

* pkg(com.fintech.life): apply suggestion from code review
2025-02-10 20:36:40 +01:00
Anonymoussaurus
91790f7612
pkg(com.android.incallui): apply suggestion from code review 2025-02-10 20:29:21 +01:00
Ricardo Fernández Serrata
1e94996dbb
refactor(deps): replace static_init by LazyLock (#808)
* refactor(deps): replace `static_init` by `LazyLock`

* docs(tests): comment to mod-comment. silence warn in `config.rs`
2025-02-09 20:53:17 +01:00
Ricardo Fernández Serrata
231fd76d6c
Merge pull request #757 from Universal-Debloater-Alliance/refactor/adb-api
refactor(ADB): improve internal API
2025-02-07 06:44:39 -04:00
Anonymoussaurus
4a2787c52d
pkg(com.google.android.photopicker): add package (#824)
* pkg(com.google.android.photopicker): add package

* pkg(com.google.android.photopicker): apply suggestion from code review
2025-02-07 01:04:37 +01:00
Anonymoussaurus
c0b29d5d30
pkg(com.oplus.aiunit): change description and removal (#823)
* pkg(com.oplus.aiunit): change description and removal

* pkg(com.oplus.aiunit): apply suggestion from code review
2025-02-07 01:04:09 +01:00
Anonymoussaurus
071325903e
pkg(oplus/oppo/oneplus): add packages (#825)
* pkg(oplus/oppo/oneplus): add packages

* pkg(com.oplus.account): apply suggestion from code review
2025-02-07 01:02:50 +01:00
Anonymoussaurus
83d1309409
pkg(com.google.android.appsearch.apk): add package (#827)
* pkg(com.google.android.appsearch.apk): add package

* pkg(com.google.android.appsearch.apk): apply suggestion from code review
2025-02-06 20:22:59 +01:00
Anonymoussaurus
955f5bb65e
pkg(com.mi.healthglobal): improve description (#829)
* pkg(com.mi.healthglobal): improve description

* pkg(com.mi.healthglobal): apply suggestion from code review
2025-02-06 20:08:55 +01:00
Anonymoussaurus
e806ba7cc9
pkg(sony): improve description and change removal (#831)
* pkg(sony): improve description and change removal

* pkg(com.google.android.euicc): apply suggestion from code review

* pkg(com.sonymobile.pobox): apply suggestion from code review
2025-02-06 19:43:38 +01:00
Anonymoussaurus
023e3d3ca5
Merge pull request #834 from Universal-Debloater-Alliance/789-pkgscope-comqualcommqtiservicessystemhelper
pkg(com.qualcomm.qti.services.systemhelper): change description and removal
2025-02-06 12:45:28 +01:00
Anonymoussaurus
f4ef57b9cc
Merge pull request #832 from Universal-Debloater-Alliance/758-adding-description-of-pkgcomopluspscanvas
pkg(com.oplus.pscanvas): add package
2025-02-06 12:45:15 +01:00
Anonymoussaurus
07fe9ec53a
Merge pull request #833 from Universal-Debloater-Alliance/761-multiple-packages-from-tcl-8182-tablet-android-810
pkg(tcl): add packages
2025-02-06 12:45:01 +01:00
Anonymoussaurus
d1bf9e9ba3
Merge pull request #828 from Universal-Debloater-Alliance/745-pkgcomqualcommqtiuceshimservice-duplicated
pkg(com.qualcomm.qti.uceshimservice): remove duplicate
2025-02-06 12:43:19 +01:00
Anonymoussaurus
2665e1bcaa
Merge pull request #821 from Universal-Debloater-Alliance/698-pkgoem-update-comxiaomibluetooth-as-safe-to-remove
pkg(com.xiaomi.bluetooth): improve description
2025-02-06 00:49:37 +01:00
Anonymoussaurus
9e73ea23a5
Merge pull request #820 from Universal-Debloater-Alliance/pkg(tracphone)-improve-descriptions-and-add-package
pkg: change descriptions and add packages
2025-02-06 00:44:07 +01:00
Anonymoussaurus
a574dfcd37
pkg(com.qualcomm.qti.services.systemhelper): change description and removal 2025-02-03 20:35:48 +01:00
Anonymoussaurus
396d43a036
pkg(tcl): add packages 2025-02-03 20:33:53 +01:00
Anonymoussaurus
bdb2c053dc
pkg(com.oplus.pscanvas): add package 2025-02-03 20:30:00 +01:00
Anonymoussaurus
16e75e8f99
Merge pull request #797 from nixingyang/xiaomi_cloud
pkg(com.miui.cloudservice and com.miui.micloudsync): update description
2025-02-03 14:48:22 +01:00
nixingyang
837ac0ee04 pkg(com.miui.cloudservice and com.miui.micloudsync): update description 2025-02-03 15:36:35 +02:00
Anonymoussaurus
1afc131979
pkg(com.qualcomm.qti.uceshimservice): remove duplicate 2025-02-02 21:24:19 +01:00
Anonymoussaurus
2a9b2675d0
pkg(com.android.incallui): change description and removal 2025-02-02 20:55:28 +01:00
Anonymoussaurus
b69cd828f9
pkg(com.xiaomi.bluetooth): improve description 2025-02-02 20:51:02 +01:00
Anonymoussaurus
e2bf544fc6
pkg: change descriptions and add packages 2025-02-02 20:36:19 +01:00
Anonymoussaurus
1adfc3c60d
Merge pull request #817 from qumuq-til/patch-3
pkg(com.android.intentresolver): improve description and change removal
2025-02-02 16:58:39 +01:00
Anonymoussaurus
bb78bc4a35
Merge pull request #812 from Universal-Debloater-Alliance/pkg/rm-distros
pkg(distro): remove community distros
2025-02-02 16:55:13 +01:00
qumuq-til
a981fb832b
Update uad_lists.json
Share is a very important part of the core OS that hardly anyone would wish to disable. Updated the description to bring attention to the word Share and moved the package from "Advanced" to "Expert".
2025-01-28 18:03:32 +03:00
Rudxain
0045a6cee5
test(ADB): add tests for PackageId::new 2025-01-26 19:55:50 -04:00
Rudxain
81a6f8459c
test: add PackageId debug-assertion to list_packages_sys 2025-01-26 19:29:57 -04:00
Rudxain
e69b9ef7f3
pkg(distro): remove community distros 2025-01-25 20:04:03 -04:00
Rudxain
06361349ba
docs(ADB): more correct module comments 2025-01-24 16:26:10 -04:00
Rudxain
080fef93bb
docs(list_users): fmt 2025-01-24 01:00:44 -04:00
Rudxain
0238982a53
docs(sync): explain why multi-user is unreliable 2025-01-23 22:26:37 -04:00
Rudxain
83f053c413
style: revert another "phone" rename. ls_users_parsed->list_users_parsed 2025-01-23 22:06:39 -04:00
Rudxain
8e8395f1d9
docs(adb): add _sys to list_packages* names 2025-01-23 21:43:26 -04:00
Rudxain
bfb97d591a
refactor: make use of reboot ADB API 2025-01-23 21:25:24 -04:00
Rudxain
a16525a4f0
feat(log): info logs for ADB API run 2025-01-23 21:21:33 -04:00
Rudxain
4f484ae7e5
refactor: undo questionable with_capacity usage
Also forgot to revert another `phone`->`device` rename
2025-01-23 20:26:56 -04:00
Rudxain
09f3ce1ebd
style: revert rename of Phone to Device (now "Phone")
Partially reverts cf054c8808

Reason: out-of-scope for PR #757
2025-01-23 20:00:39 -04:00
Rudxain
a1762c20c9
style(settings-view): fully-qualified iced::Command 2025-01-23 19:54:30 -04:00
Rudxain
0f48489e5c
docs(ADB): readable names, and better comments 2025-01-23 19:41:37 -04:00
Rudxain
74a5c5e3ff
style: cargo fmt 2025-01-20 16:28:02 -04:00
Rudxain
12ca4f64bc
chore: forgot to rm UNINSTALLED_PACKAGES_FILE_NAME
this should've been fixed when resolving the merge-conflict
2025-01-20 16:20:53 -04:00
Ricardo Fernández Serrata
ef160366c7
Merge branch 'main' into refactor/adb-api 2025-01-20 16:15:53 -04:00
Antonino Scordino
bfda7d0a8e
pkg(Google): add and clarify package(s) description (#805)
* add description for 'com.google.android.apps.weather'
 * update descritpion for Digital Wellbeing
 * update description and dependencies for Permission Controller
 * update description for Safety Center

Change-Id: Id9f69dd3b23e0603a6a77ab9bfeb46d541446b71
2025-01-20 20:53:57 +01:00
Adhiraj S. Chauhan
37b39e8622
Merge pull request #806 from Universal-Debloater-Alliance/ui/filter-all
feat(ui): clearer "All" filters
2025-01-20 14:08:22 +00:00
Adhiraj S. Chauhan
f57f5d39b5
Merge pull request #807 from Universal-Debloater-Alliance/adb-retry-fast
feat(ADB): retry `adb devices` only 3 times in debug builds
2025-01-20 14:04:24 +00:00
Rudxain
31fccce97f
feat(ADB): retry adb devices only 3 times in debug builds 2025-01-19 23:47:20 -04:00
Rudxain
8bf930ffa6 feat(ui): clearer "All" filters 2025-01-19 23:10:19 -04:00
Ricardo Fernández Serrata
0cff895c8e
Merge pull request #799 from Universal-Debloater-Alliance/refactor/extract-uninstalled_packages_file_name_format-into-const
refactor: extract UNINSTALLED_PACKAGES_FILE_NAME_FORMAT into a const
2025-01-16 18:07:01 -04:00
Rudxain
60ec9f3f1a
refactor: define fn to generate backup file-name 2025-01-16 17:59:31 -04:00
Rudxain
66021c2828
chore: fix compile err by splitting backup name and format strings as 2 consts 2025-01-16 17:09:02 -04:00
Adhiraj Singh Chauhan
d14ed459f7
refactor: extract UNINSTALLED_PACKAGES_FILE_NAME_FORMAT into a const 2025-01-16 17:08:55 +05:30
Adhiraj S. Chauhan
2673fd5c70
Merge pull request #796 from Universal-Debloater-Alliance/631-bugscope-export-uninstalled-packages-with-their-description-success-message-references-txt-file-instead-of-csv
bug(settings): use csv instead of txt for `uninstalled_packages`
2025-01-14 11:11:28 +00:00
Anonymoussaurus
fadef4ef39
bug(settings): use csv instead of txt for uninstalled_packages
Fixes #631
2025-01-14 16:36:29 +05:30
Anonymoussaurus
c9eeed3d7d
Merge pull request #793 from Universal-Debloater-Alliance/fix-incorrect-ci-file
build(ci): remove exclude and add MacOS-13 to CI
2025-01-13 22:45:29 +01:00
Anonymoussaurus
2d77c15fe1
build(ci): remove exclude and add MacOS-intel to CI 2025-01-13 21:57:44 +01:00
Anonymoussaurus
ad4598ea1f
Merge pull request #791 from Universal-Debloater-Alliance/722-bugci-latest-release-artifact-not-working-on-macos-ventura-intel
build(ci): add runner for MacOS with Intel CPU
2025-01-12 22:52:13 +01:00
Anonymoussaurus
467aa379b6
build(ci): add runner for MacOS with Intel CPU 2025-01-12 17:17:37 +01:00
Ricardo Fernández Serrata
6991c2adb6
Merge pull request #788 from Universal-Debloater-Alliance/dl2
chore(deps): upgrade to `dark-light` v2
2025-01-12 01:31:28 -04:00
Ricardo Fernández Serrata
784678c8c2
Merge pull request #786 from Universal-Debloater-Alliance/781-buildci-remove-deepsource-check
build(ci): remove DeepSource check
2025-01-12 01:22:40 -04:00
Unchanged4352
a97f10c063
pkg(com.android.phone): improve description and change removal type (#790)
* typo

* Update

* update

* fix
2025-01-11 18:27:06 +01:00
Rudxain
fb5a3f9d09
chore(deps): upgrade to dark-light v2 2025-01-09 20:23:50 -04:00
Anonymoussaurus
83b24d5f2e
build(ci): remove DeepSource check 2025-01-09 00:41:02 +01:00
ajax
5b41af4d05
pkg(com.android.thememanager): improve description (#783)
* Update uad_lists.json

* Removed space as per request

* Update uad_lists.json
2025-01-09 00:36:36 +01:00
Anonymoussaurus
40603935ac
pkg(com.heytap.pictorial): add note about wallpaper carousel (#678)
* pkg(com.heytap.pictorial): add note about wallpaper carousel

* pkg(com.heytap.pictorial): apply code suggestion

* pkg(com.heytap.pictorial): change removal

---------

Co-authored-by: schbrns <149918978+schbrns@users.noreply.github.com>
Co-authored-by: Ricardo Fernández Serrata <76864299+Rudxain@users.noreply.github.com>
2025-01-07 22:17:03 +01:00
Anonymoussaurus
f64e62758d
Merge pull request #778 from Universal-Debloater-Alliance/pkg/grammar
pkg(samsung): fix grammar and formatting for some Galaxy packs
2025-01-06 19:02:24 +01:00
Anonymoussaurus
de58efad11
Merge pull request #777 from Universal-Debloater-Alliance/pkg/samsung/themes
pkg(samsung themes): add wallpaper breakage info, remove redundancy
2025-01-06 18:59:11 +01:00
Ricardo Fernández Serrata
cfd6835bfa
pkg(samsung): improve S-location related descriptions (#773)
* pkg(Samsung): improve com.samsung.android.location description

* pkg(Samsung-location): improve descriptions for location SDK & history

* pkg(Samsung): add "Slocation" display-name

* pkg(Samsung): minor edit

* pkg(Samsung): add Slocation link
2025-01-06 18:55:33 +01:00
MCPEngu
374bf82e97
pkg(com.samsung.android.app.dtv.dmb): add package (#769)
* Add new package

com.samsung.android.app.dtv.dmb

* Update uad_lists.json
2025-01-06 18:27:57 +01:00
Anonymoussaurus
2b615d7bc4
Merge pull request #768 from Universal-Debloater-Alliance/pkg-FACM
pkg(Samsung): ACM = FACM
2025-01-06 18:18:41 +01:00
Ricardo Fernández Serrata
d9c0e508a0
Merge pull request #780 from nixingyang/com.xiaomi.market
pkg(com.xiaomi.market): categorize it as Advanced
2025-01-05 20:36:52 -04:00
nixingyang
3a95292f97 pkg(com.xiaomi.market): categorize it as Advanced 2025-01-05 10:37:30 +02:00
Rudxain
da03c8bab2
pkg(samsung): fix grammar and formatting for some Galaxy apps:
- `com.samsung.android.mdecservice`
- `com.samsung.klmsagent`
2025-01-03 19:19:49 -04:00
Rudxain
efa828f8da
pkg(samsung themes): add wallpaper breakage info, remove redundancy 2025-01-03 18:53:17 -04:00
Rudxain
f9e460222e
pkg(Samsung): ACM = FACM 2024-12-26 12:33:25 -04:00
Unchanged4352
beeaf94769
pkg(com.android.wallpaperbackup): fix typo in description (#728)
* typo

* Update
2024-12-17 16:52:34 +01:00
Anonymoussaurus
63deae41c5
Merge pull request #737 from Universal-Debloater-Alliance/692-pkgscope-add-htc-packages
pkg(htc): add HTC Lockscreen and Weather themes
2024-12-17 16:39:42 +01:00
schbrns
49d6234bbe pkg(uad_lists): add HTC Lockscreen and Weather themes 2024-12-17 16:36:16 +01:00
Rudxain
fc72efc639
docs: iced::Command as ICmd, and potential RCE warn
Also merge some `use`s
2024-12-15 23:26:46 -04:00
Rudxain
5e27a52481
refactor(utils): less dupes in open_url 2024-12-15 23:25:39 -04:00
Rudxain
e84e08118b
refactor(ADB): add getprop API, inline adb_cmd into adb_sh_cmd
Also make `get_device_brand` more honest
2024-12-15 23:24:25 -04:00
Rudxain
2e2114d778
docs(ADB): more specific; mention assumptions 2024-12-15 21:11:36 -04:00
Rudxain
9aeba115a6
refactor: user_id: u16 not u: User 2024-12-15 20:56:39 -04:00
Rudxain
4ec1acd769
refactor: replace hashset_system_packages by new API 2024-12-15 20:13:50 -04:00
Rudxain
4c61dc32f5
docs(ADB): more docs for ls_packs*, and validated returns Set 2024-12-15 19:49:27 -04:00
Rudxain
77a52be830
refactor: more pre-parsing 2024-12-14 20:41:31 -04:00
Rudxain
240dde1a97
refactor: create adb module, and add **LOTS** of docs 2024-12-14 18:21:04 -04:00
Rudxain
a566733df0
refactor: add PackId, replace list_all_system_packages by list_packs 2024-12-14 12:56:48 -04:00
Rudxain
c172baede7
fix: User not &User 2024-12-14 11:11:15 -04:00
Anonymoussaurus
1ed216ac6a
Merge pull request #754 from Universal-Debloater-Alliance/docs/README
docs(readme): improve disclaimer and link to Rust website
2024-12-10 20:28:38 +01:00
Anonymoussaurus
647aafe921
Merge pull request #755 from Universal-Debloater-Alliance/adb-version-issue
chore(issue-template): add ADB version field for bug-report
2024-12-10 20:27:21 +01:00
Ricardo Fernández Serrata
f38ad6fe1d
chore(issue-template): add ADB version field for bug-report 2024-12-10 08:41:35 -04:00
Ricardo Fernández Serrata
3519662fa8
docs(README): improve disclaimer and link to Rust org 2024-12-10 08:20:53 -04:00
Rudxain
30359cb684
refactor: use AdbCmd, finish list_packs and add list_users 2024-12-08 12:59:50 -04:00
Rudxain
87fa332082
docs(sync): Mention type-sys patterns on AdbCmd 2024-12-08 12:53:32 -04:00
Rudxain
b74947edff
feat: add type-state cmd builders 2024-12-08 12:53:32 -04:00
Rudxain
04b3ef597e
docs(sync): mention pm list format assumption 2024-12-08 05:30:47 -04:00
Rudxain
89680fc217
perf: use more Vec::with_capacity 2024-12-08 05:20:48 -04:00
Rudxain
ac056ddafa
perf: Optimize *system_packages and improve list_all_system_packages API 2024-12-08 04:49:57 -04:00
Rudxain
dc1ce193fa
style: vec macro 2024-12-08 04:36:48 -04:00
Rudxain
f0f6c51749
docs: vec cap can't overflow 2024-12-08 00:48:18 -04:00
deepsource-autofix[bot]
7052646e9a
style: format code with Rustfmt
This commit fixes the style issues introduced in 1da5b69 according to the output
from Rustfmt.

Details: https://github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation/pull/653
2024-12-08 04:13:42 +00:00
Rudxain
1da5b69cfe
refactor: cargo clippy --fix 2024-12-08 00:13:23 -04:00
Ricardo Fernández Serrata
65349ecbcd
Merge branch 'main' into refactor/sync-and-set_var 2024-12-08 00:03:45 -04:00
Ricardo Fernández Serrata
b8f6688e81
Merge pull request #730 from Universal-Debloater-Alliance/729-bugci-macos-lint-fails
build(ci): fix macOS linting failing
2024-12-08 00:01:13 -04:00
Rudxain
f151f54df4
test(theme): skip comparing palette.bright.surface 2024-12-07 23:57:05 -04:00
Rudxain
160c4c9bc4
Revert "build(ci): add debugging for testing"
This reverts commit f4ad450b20.
2024-12-07 23:54:29 -04:00
Rudxain
619fc83996
Revert "build(ci): allow bright.surface to be black for specific scenarios"
This reverts commit 36da706cc6.
2024-12-07 23:53:59 -04:00
Ricardo Fernández Serrata
5761e8df9b
Merge branch 'main' into refactor/sync-and-set_var 2024-12-07 10:25:49 -04:00
Rudxain
5300befea8
refactor: strs are Options already! 2024-12-07 10:17:59 -04:00
deepsource-autofix[bot]
db15305185
style: format code with Rustfmt
This commit fixes the style issues introduced in fed1580 according to the output
from Rustfmt.

Details: https://github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation/pull/653
2024-12-07 13:23:25 +00:00
Rudxain
fed1580e20
refactor: avoid set_var by specifying serial 2024-12-07 09:20:17 -04:00
Rudxain
cf054c8808
docs: Phone -> Device, and explain fields 2024-12-07 04:15:10 -04:00
Rudxain
c0fa888a5a
chore: derive Copy for Error 2024-12-07 02:44:44 -04:00
Anonymoussaurus
25dfa8b075
Merge pull request #750 from jcoffa/main
pkg(com.telus.checkup): add checkup package from Canadian carrier Telus
2024-12-03 10:35:04 +01:00
Joseph Coffa
e3eb8454d0 pkg(com.telus.checkup): add checkup package from Canadian carrier Telus 2024-12-02 23:19:39 -05:00
Frigyes
fc125a5f67
Merge pull request #744 from Universal-Debloater-Alliance/readme/link-to-discussion-about-needing-contributors
docs(readme): link to discussion about needing developers
2024-11-26 16:07:26 +00:00
Anonymoussaurus
052f6d5166
docs(readme): link to discussion about needing developers 2024-11-26 14:54:38 +01:00
Anonymoussaurus
88d9464f60
Merge pull request #735 from Universal-Debloater-Alliance/689-update-description-of-pkgcomandroidse
pkg(com.android.se): dep of ColorOS lock
2024-11-25 23:03:35 +01:00
Anonymoussaurus
b198a707cc
Merge pull request #739 from Universal-Debloater-Alliance/710-pkgscope-move-comlgeprovidersignboard-to-expert-breaks-settings
pkg(com.lge.provider.signboard): change description and removal
2024-11-25 22:35:33 +01:00
Anonymoussaurus
b3bfd21cf4
Merge pull request #738 from Universal-Debloater-Alliance/697-pkgsamsung-comsamsungsmt-description
pkg(com.samsung.SMT): change removal to "advanced"
2024-11-25 22:32:01 +01:00
Anonymoussaurus
fd5eb599ec
Merge pull request #736 from Universal-Debloater-Alliance/690-pkgcomhuaweilbs-causing-bootloop-on-huawei-matepad-115s-papermatte
pkg(com.huawei.lbs): update description for Huawei LBS and change removal recommendation
2024-11-25 22:28:57 +01:00
schbrns
c8c0288dac fix(uad_lists.json): update com.lge.provider.signboard description and modify removal recommendation to expert 2024-11-25 03:25:04 -05:00
schbrns
0702ae4800 fix(uad_lists.json): update SMT category from "Recommended" to "Advanced" 2024-11-25 03:12:35 -05:00
schbrns
d1f5cd3822 docs(uad_lists.json): update description for Huawei LBS and change removal recommendation 2024-11-25 02:54:39 -05:00
schbrns
f2c0c1d4a9 Update uad_lists.json 2024-11-25 02:32:06 -05:00
Ricardo Fernández Serrata
5fa7a0e426
Merge pull request #734 from Universal-Debloater-Alliance/613-pkgscope-removing-wallpaper-services-breaks-lock-star
pkg(com.samsung.android.dynamiclock) Breaks LockStar customizations
2024-11-25 03:01:52 -04:00
schbrns
af12a9a102 Update uad_lists.json 2024-11-24 21:37:00 -05:00
Anonymoussaurus
0ef8bdf7aa
Revert "build(ci): create default configuration for test"
This reverts commit 55af9605a4.
2024-11-23 20:09:18 +01:00
Anonymoussaurus
2c5aee846d
Revert "build(ci): ensure device list is not empty"
This reverts commit fa69801e99.
2024-11-23 20:08:04 +01:00
Anonymoussaurus
fa69801e99
build(ci): ensure device list is not empty 2024-11-23 20:01:10 +01:00
Anonymoussaurus
55af9605a4
build(ci): create default configuration for test 2024-11-23 19:59:37 +01:00
Anonymoussaurus
36da706cc6
build(ci): allow bright.surface to be black for specific scenarios 2024-11-23 16:28:12 +01:00
Anonymoussaurus
f4ad450b20
build(ci): add debugging for testing 2024-11-23 16:17:40 +01:00
Frigyes
9295c8bcd7
Merge pull request #704 from Universal-Debloater-Alliance/ci/lint/allow_with_reason
ci(lint): `warn` on `allow_attributes_without_reason`
2024-11-17 22:37:04 +00:00
Unchanged4352
1e8204b400
pkg(com.taboola.scoop): add wallpaper carousel package (#714)
* Added com.taboola.scoop

* Fixes
2024-11-14 00:22:32 +01:00
Ricardo Fernández Serrata
a25efe0286
Merge pull request #654 from Universal-Debloater-Alliance/build/unit-tests
build(ci): add new unit tests
2024-11-03 21:14:02 -04:00
Adhiraj S. Chauhan
91341a5a43
Merge pull request #702 from Universal-Debloater-Alliance/hotfix/auto-theme
fix(theme): fix, patch, and optimize(`perf`) `Auto` theme
2024-11-04 01:41:23 +05:30
Anonymoussaurus
62df44fce8
pkg(com.google.android.apps.messaging): add notice for Unihertz users (#684)
* pkg(com.google.android.apps.messaging): add notice for Unihertz users

* pkg(com.google.android.apps.messaging): apply suggestion from review
2024-11-02 20:26:57 +01:00
Rudxain
cb83e84789
docs(theme): reminder to sync icon and GUI color-schemes 2024-10-29 19:10:25 -04:00
Rudxain
fb3286d9d0
fix(run-time): make OS_COLOR_SCHEME a lazy static 2024-10-29 18:57:36 -04:00
Ricardo Fernández Serrata
29673ef74c
ci(lint): warn on allow_attributes_without_reason 2024-10-29 14:36:10 -04:00
Anonymoussaurus
897ef8af6f
pkg(samsung): change removal of 2 packages (#679)
* pkg(samsung): change removal of 2 packages

* pkg(com.samsung.android.app.routines): apply suggestion from review
2024-10-28 21:24:07 +01:00
Anonymoussaurus
317c12b4a4
Merge pull request #683 from Universal-Debloater-Alliance/665-delete-commiuiaod-from-recommended-debloat-list
pkg(com.miui.aod): change removal to advanced
2024-10-28 20:24:47 +01:00
Rudxain
24a61c8b04
fix(theme): fix, patch, and optimize(perf) Auto theme 2024-10-27 22:15:09 -04:00
Anonymoussaurus
47980f635e
pkg(tcl): add com.jrdcom.urlreservedapp1 (#680)
* pkg(tcl): add `com.jrdcom.urlreservedapp1`

* pkg(com.jrdcom.urlreservedapp1): apply suggestion from review
2024-10-27 22:32:49 +01:00
Anonymoussaurus
d098b58528
pkg(com.samsung.euicc): change removal and improve description (#682)
* pkg(com.samsung.euicc): change removal and improve description

* pkg(com.samsung.euicc): apply suggestion from review
2024-10-27 22:32:08 +01:00
Anonymoussaurus
88b6ab468c
pkg(com.google.android.apps.privacy.wildlife): add package (#672)
* pkg(com.google.android.apps.privacy.wildlife): add package

* pkg(com.google.android.apps.privacy.wildlife): apply suggestion from review
2024-10-27 22:31:35 +01:00
Anonymoussaurus
620e00b34a
pkg(com.coloros.recents): fix incorrect description and removal (#673)
* pkg(com.coloros.recents): fix incorrect description and removal

* pkg(com.coloros.recents): apply suggestion from review
2024-10-27 22:29:49 +01:00
Anonymoussaurus
1966bfdb75
Merge pull request #676 from Universal-Debloater-Alliance/576-pkgcomnothingthirdparty-uninstall-breaks-glyph-feature
pkg(com.nothing.thirdparty): change description and removal
2024-10-27 12:55:20 +01:00
Anonymoussaurus
00633d2bcc
Merge pull request #675 from Universal-Debloater-Alliance/572-comcasperturkiye-seems-to-be-just-aosp-crap
pkg(com.casper.turkiye): add package
2024-10-27 12:52:37 +01:00
Anonymoussaurus
ee31d1e4e3
Merge pull request #677 from Universal-Debloater-Alliance/585-pkgscope-recommended-debloat-issue-on-oppo
pkg(com.coloros.weather.service): change description and removal
2024-10-27 12:52:08 +01:00
Anonymoussaurus
c3fe1a4666
Merge pull request #660 from Universal-Debloater-Alliance/pkg/ali
pkg(Alibaba): add AliExpress
2024-10-22 18:39:34 +02:00
Ricardo Fernández Serrata
26aee1ef43
Merge pull request #674 from Universal-Debloater-Alliance/571-recommended-apps-breaks-system-navigation
pkg(google): change overlay removals to expert
2024-10-20 17:27:37 -04:00
Anonymoussaurus
2e0a87a97b
Merge branch 'main' into 571-recommended-apps-breaks-system-navigation 2024-10-15 16:56:30 +02:00
Ricardo Fernández Serrata
d6cb3ce59e
Merge pull request #685 from Universal-Debloater-Alliance/669-pkgscope-move-comsamsungandroidmobileservice-to-advanced-list
pkg(com.samsung.android.mobileservice): change removal to advanced
2024-10-14 08:29:34 -04:00
Rudxain
70d278db68
build(lint): allow unwrap for tests 2024-10-14 07:52:18 -04:00
Anonymoussaurus
56aedda47d
Merge pull request #681 from Universal-Debloater-Alliance/649-some-apps-are-incorrectly-labeled-as-recommended
pkg(google): change description and removal for 2 packages
2024-10-10 08:19:53 +02:00
Ricardo Fernández Serrata
252ca79b08
Merge pull request #671 from Universal-Debloater-Alliance/513-pkgstate-unable-to-remove-samsung-game-optimizing-service
pkg(com.samsung.android.game.gos): add notice about disabling
2024-10-10 01:33:12 -04:00
Adhiraj S. Chauhan
907a34780d
Merge pull request #664 from Universal-Debloater-Alliance/docs(readme)-fix-missing-Discord-badge
docs(readme): fix broken invite and image
2024-10-05 22:40:13 +05:30
Frigyes
0636dbb9f8
build(test): change test according to suggestion 2024-10-05 16:46:04 +00:00
Anonymoussaurus
17b637d06c
pkg(com.samsung.android.mobileservice): change removal to advanced 2024-10-05 13:15:34 +02:00
Anonymoussaurus
8dc818e0df
pkg(com.miui.aod): change removal to advanced 2024-10-05 13:11:50 +02:00
Anonymoussaurus
0e5a58ca5f
pkg(google): change description and removal for 2 packages 2024-10-05 13:08:36 +02:00
Anonymoussaurus
ac7eab55b9
pkg(com.coloros.weather.service): change description and removal 2024-10-05 12:51:26 +02:00
Anonymoussaurus
97221d1a3c
pkg(com.nothing.thirdparty): change description and removal 2024-10-05 12:48:28 +02:00
Anonymoussaurus
9ef748ec1d
pkg(com.casper.turkiye): add package 2024-10-05 12:45:25 +02:00
Anonymoussaurus
510afbe992
pkg(google): change overlay removals to expert 2024-10-05 12:42:28 +02:00
Anonymoussaurus
c79c8826d6
pkg(com.samsung.android.game.gos): add notice about disabling 2024-10-05 12:32:06 +02:00
Anonymoussaurus
c70877dfdb
docs(readme): fix broken invite and image 2024-10-03 15:10:06 +02:00
Ricardo Fernández Serrata
f22f5e3672
pkg(Alibaba): add AliExpress 2024-09-29 16:52:13 -04:00
Anonymoussaurus
4541552975
Merge pull request #659 from Universal-Debloater-Alliance/chore/hotfix/bug-template
chore(1-bug-report.yml): fix rendering error
2024-09-29 22:43:08 +02:00
Ricardo Fernández Serrata
b3c1d4787c
fix(1-bug-report.yml): rendering error 2024-09-29 16:38:28 -04:00
Anonymoussaurus
ee7fdd9184
Merge pull request #656 from Universal-Debloater-Alliance/chore/fix/issue-template-logs
chore(`bug-report.yml`): collapse log contents
2024-09-26 18:04:09 +02:00
Ricardo Fernández Serrata
66be4a2610
chore(bug-report.yml): collapse log contents 2024-09-26 11:52:57 -04:00
Ricardo Fernández Serrata
8ee7b0b4e9
refactor: Avoid clone in assignments (#655)
* codecov: RS-W1070

* fix(vars): var-name merge-conflict

---------

Co-authored-by: Himadri Bhattacharjee <107522312+lavafroth@users.noreply.github.com>
2024-09-26 09:44:16 +02:00
Frigyes Erdosi Szucs
0dbcfd62d7
misc(test): fix assertion typo 2024-09-25 12:41:05 -07:00
Frigyes Erdosi Szucs
3157744954
Merge commit '7603c0f767' into build/unit-tests 2024-09-25 12:35:47 -07:00
Frigyes Erdosi Szucs
6cc8c6bdee
misc(anti-pattern): replace boolean assert eq with assert 2024-09-25 12:31:55 -07:00
Frigyes Erdosi Szucs
aeddfdf1bf
mics(style): apply fmt fixes 2024-09-25 12:26:23 -07:00
deepsource-autofix[bot]
7603c0f767
style: format code with Rustfmt
This commit fixes the style issues introduced in 146a159 according to the output
from Rustfmt.

Details: https://github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation/pull/654
2024-09-25 19:24:54 +00:00
Frigyes Erdosi Szucs
146a15943c
build(test): added some more unit tests 2024-09-25 12:23:31 -07:00
Rudxain
63707f343f style(sync): readable consts
https://github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation/pull/653#discussion_r1774515159
2024-09-25 11:04:35 -04:00
codenyte
3727469c8f
pkg(com.mig.play.games): add Funmax package (#652)
* Add "Funmax" app to Recommended list

* Fix mistake
2024-09-25 13:12:44 +02:00
Adhiraj S. Chauhan
0f22407f06
Merge pull request #636 from Universal-Debloater-Alliance/563-pkgscope-update-for-multiple-packages
pkg(samsung): change removal and descriptions of multiple packages
2024-09-25 10:49:59 +05:30
Adhiraj S. Chauhan
f4ed1e5c8f
Merge pull request #635 from Universal-Debloater-Alliance/558-pkgscope-comsamsungadnroidknoxappnetworkfilter-uninstalling-crashes-bluetooth
pkg(com.samsung.android.knox.app.networkfilter): change removal and description
2024-09-25 10:49:23 +05:30
Adhiraj S. Chauhan
14fed78d16
Merge pull request #634 from Universal-Debloater-Alliance/557-pkgcommiuiguardprovider-change-description
pkg(com.miui.guardprovider): improve description
2024-09-25 10:48:52 +05:30
Rudxain
8bead68916 style: rm unused imports 2024-09-24 18:28:02 -04:00
Rudxain
6032b8e5e4 build(lint): improve warns about unsafe 2024-09-24 18:20:35 -04:00
Rudxain
8a80cdc921 refactor(set_var-serial): define set_adb_serial 2024-09-24 18:05:19 -04:00
Rudxain
8ddbe68ebe refactor(sync): const pm {list packages | clear} 2024-09-24 17:38:16 -04:00
Anonymoussaurus
e595973cb4
Merge pull request #648 from Nathawat-GH/main
pkg(com.miui.aod): add lock screen editor feature to description
2024-09-24 10:53:38 +02:00
Scott
6515aaf2b2
pkg(com.miui.aod): Add lock screen editor feature to description 2024-09-24 12:02:12 +07:00
Anonymoussaurus
5394f720b4
pkg(com.google.android.setupwizard): improve description (#637)
* pkg(com.google.android.setupwizard): improve description

* pkg(com.google.android.setupwizard): add notice

* pkg(com.google.android.setupwizard): improve description
2024-09-19 10:34:21 +02:00
Adhiraj S. Chauhan
a04d597c04
Merge pull request #626 from Universal-Debloater-Alliance/build/opt-release
build(ci): optimize Cargo `release` for program
2024-09-19 01:53:08 +05:30
Anonymoussaurus
9807b42665
pkg(com.hoffnung): improve description (#633)
* pkg(com.hoffnung): improve description

* pkg(com.hoffnung): add 'may'
2024-09-18 15:44:50 +02:00
Anonymoussaurus
0f42a6974a
pkg(samsung): change removal and descriptions of multiple packages 2024-09-18 15:40:02 +02:00
Anonymoussaurus
c8f109290a
pkg(com.samsung.android.knox.app.networkfilter): change removal and description 2024-09-18 15:30:31 +02:00
Anonymoussaurus
eb197ce933
pkg(com.miui.guardprovider): improve description 2024-09-18 15:27:51 +02:00
Ricardo Fernández Serrata
1b3e1f380e
build(Cargo): optimize release further 2024-09-15 11:28:18 -04:00
Anonymoussaurus
4b12d034d1
Merge pull request #551 from Universal-Debloater-Alliance/chore/1.1.0-release-preparation
chore(release): preparation for v1.1.0
2024-09-15 16:26:30 +02:00
Himadri Bhattacharjee
a0b0d6e178
feat: add Nix flake (#421)
* feat: add flake.nix

* feat: update flake.nix for wayland compatibility

* fix: remove GL dependency

* deps: remove expat unused in latest version of iced
2024-09-15 16:24:46 +02:00
Ivy
50a27d6883
pkg(motorola): add packages (#610)
* pkg(motorola): add packages

* Update some Motorola descriptions and removals 

thanks schbrns for the updated descriptions

* change com.motorola.setup.auto_generated_rro_product__ to expert

* Add missing comma

* Add another missing comma

ivy try to remember commas challenge (impossible)
2024-09-14 18:14:36 +02:00
Anonymoussaurus
5679cf66c6
Merge pull request #620 from Universal-Debloater-Alliance/fix-legacy-uninstall
fix: use `pm block` and `pm clear` for sdk versions below 19
2024-09-14 16:13:40 +02:00
Ricardo Fernández Serrata
b50d7af4b8
refactor(linting): fix warnings from #537 (#578)
* refactor(apply-lints): `cargo clippy --fix`

* style: format code with Rustfmt

This commit fixes the style issues introduced in 7c04d15 according to the output
from Rustfmt.

Details: https://github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation/pull/578

* style(save): call unqualified `Ok`

* style(sync): inline fmt args on `info!`

* style(theme): properly separate hex colors, `allow` `match_same_arms`

* refactor(list-view): `allow` some lints, dedupe text widget

* refactor(list-view): fix 1 `if_not_else`

* fix(utils): `setup_uad_dir` no longer takes `Option`

Also more logging and error handling

* refactor(list-view): `export_selection` `Button` built with common branch

* fix(list-view): fix all warns in 1 file, refactor, err handling, etc...

* style: format code with Rustfmt

This commit fixes the style issues introduced in 49cfa27 according to the output
from Rustfmt.

Details: https://github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation/pull/578

* refactor(lints): `allow`, `expect`, and apply lints. factor `uad_lists.json` into var
Also:
- factors-out the List name into a `const`.
- Converts some regular comments into docs.
- use `reason` as a better alternative to comments.

* docs(name): concise description of `NAME`

* style(theme): apply suggestion from review

---------

Co-authored-by: Rudxain <rudxain@localhost.localdomain>
Co-authored-by: deepsource-autofix[bot] <62050782+deepsource-autofix[bot]@users.noreply.github.com>
2024-09-14 16:13:05 +02:00
Himadri Bhattacharjee
5c408b903d
docs(public-functions): add documentation for public functions in sync.rs (#621)
* docs: add docs for ADB `request_builder` in sync.rs

* docs: more docs for sync.rs functions
2024-09-13 10:23:52 +02:00
Himadri Bhattacharjee
0f59a412e4
fix: use pm block and pm clear for sdk versions below 19 2024-09-12 22:14:59 +05:30
Ricardo Fernández Serrata
2a1ebbaa1d
chore(issue-template): improve correctness, privacy, and comprehensiveness (#606)
* chore(bug_template): improve correctness, privacy, and comprehensiveness

* chore(bug_template): fix syntax errors

* chore(bug_template): move MD links to MD section

They didn't render as intended

* chore(bug_template): clarify logfile
2024-09-10 22:29:34 +02:00
Anonymoussaurus
821587d045
Merge pull request #611 from mirko93s/main
added com.android.settingsaccessibility
2024-09-07 19:47:33 +02:00
mirko93s
527837bed1
added com.android.settingsaccessibility
stock android accessiblity setting afaik but in my lg v30 the package is named settings instead of setting
2024-09-07 19:24:39 +02:00
Ricardo Fernández Serrata
ee4958abd0
pkg(samsung): alt names, missing packs, fmt list (#555)
* docs(pkg-samsung): alt names, and #554

* style(list): revert some fmt

* style(list): revert some fmt

* docs(pkg): style: description

* pkg(Google): "Private Compute Services" desc

* pkg(Samsung): describe Smart Touch Call

* pkg(Samsung): add name "Samsung Editing Assets"

* pkg(Samsung): add missing packs

---------

Co-authored-by: Rudxain <rudxain@localhost.localdomain>
2024-09-06 19:39:35 +02:00
Anonymoussaurus
56d2459317
Merge pull request #609 from Universal-Debloater-Alliance/pkg/tpms
pkg(infinix): inform about bootloop and change `removal` to `unsafe`
2024-09-06 10:46:36 +02:00
Ricardo Fernández Serrata
e9c4f680a2
pkg(tpms): BOOTLOOP WARN. Removal Unsafe 2024-09-06 03:30:29 -04:00
Adhiraj S. Chauhan
d1a7eb1cd6
Merge pull request #603 from Universal-Debloater-Alliance/feat/app_id
refactor(app_id): specify `iced::Settings.id`
2024-09-04 12:14:00 +05:30
Rudxain
15895fe036 refactor(name): use NAME wherever possible 2024-09-04 02:28:11 -04:00
Rudxain
f78082d679 refactor(name): define app NAME 2024-09-04 02:04:50 -04:00
Rudxain
f90a9e4a63 feat(app_id): Specify iced::Settings.id 2024-09-04 01:49:04 -04:00
Lost-Entrepreneur439
4f9332c2c2
pkg(samsung): add packages (#600)
* pkg(samsung): Add 9 missing Samsung packages

* pkg(samsung): Change com.samsung.android.app.colorblind to Advanced

* pkg(samsung): Change com.sec.app.TransmitPowerService to Expert
2024-09-02 23:36:01 +02:00
Anonymoussaurus
e6e2f9ff66
pkg(oneplus): add packages and improve descriptions (#581)
* pkg(oneplus): improve descriptions

* pkg(oneplus): add packages

* pkg(oneplus): fix typos in dependencies

* pkg(oneplus): incorporate suggestions from review
2024-09-02 11:03:16 +02:00
Ricardo Fernández Serrata
255733c420
docs(contributing): recommend rebase from main (#597)
* docs(CONTRIBUTING): recommend `rebase` from `main`

* docs(contrib): clarify non-main paragraph

* docs(contrib): rm "AKA"

* docs(contrib): more explicit

* docs(contrib): team, not org

---------

Co-authored-by: Rudxain <rudxain@localhost.localdomain>
2024-09-01 11:41:34 +02:00
Anonymoussaurus
628fe0c87f
Merge pull request #593 from Universal-Debloater-Alliance/docs/pkg/chrome
pkg(com.android.chrome): add note about passkeys to description
2024-08-25 13:27:07 +02:00
Rudxain
dfa33cf82b pkg(Chrome): it may not be necessary for passkeys 2024-08-24 18:06:12 -04:00
Anonymoussaurus
dcfe757e30
Merge pull request #588 from alvinkim101/change-description-and-removal-for-com.lge.sui.widget
pkg(com.lge.sui.widget): change description and removal
2024-08-22 14:09:10 +02:00
Alvin Kim
f0fcf44620 pkg(com.lge.sui.widget): reword description 2024-08-20 16:17:15 -07:00
Alvin Kim
f011a0776c pkg(com.lge.sui.widget): change description and removal 2024-08-20 16:11:55 -07:00
Anonymoussaurus
584451d364
Merge pull request #587 from Universal-Debloater-Alliance/chore/cargo-config-toml
chore(cargo): append ".toml" to `config`
2024-08-19 21:03:31 +02:00
Rudxain
594eeed7d0 chore(cargo): append ".toml" to config 2024-08-19 14:50:57 -04:00
Anonymoussaurus
84b2363aec
Merge pull request #586 from jxdv/update-verizon-pkg-desc
pkg(com.customermobile.preload.vzw): update description with security finding
2024-08-19 17:49:57 +02:00
jxdv
a834757db6 update desc 2024-08-19 17:42:47 +02:00
jxdv
e626ac0871 update description 2024-08-19 09:42:34 +02:00
jxdv
03807ae290 update description with security finding 2024-08-19 09:42:34 +02:00
Adhiraj S. Chauhan
4b7c96e429
Merge pull request #582 from Universal-Debloater-Alliance/build/ci/warn-as-warn
build(ci): treat warns as warns
2024-08-19 08:48:57 +05:30
Ricardo Fernández Serrata
d95217c3ac
build(ci): treat warns as warns 2024-08-10 14:13:45 -04:00
Ricardo Fernández Serrata
413634eca8
build(linting): Merge pull request #537 from /build/add-lints
build(linting): add more lints
2024-08-06 16:28:00 -04:00
Anonymoussaurus
742f0b6744
Merge pull request #575 from anuraggr/main
pkg(com.preff.kb.xm): add package
2024-08-05 23:51:37 +02:00
Anurag Rai
748ea1e355
removed the space 2024-08-05 18:10:42 +05:30
Anurag Rai
ff86c4b046
Changed from recommanded to advanced for com.preff.kb.xm 2024-08-05 18:08:47 +05:30
Anurag Rai
196814492d
Add description for com.preff.kb.xm 2024-08-05 17:29:02 +05:30
Anurag Rai
f737dd4d72
Add com.preff.kb.xm (Oem keyboard on hyperos) 2024-08-05 16:48:06 +05:30
Anonymoussaurus
da9b34c25b
Merge pull request #573 from himazawa/main
pkg(Onyx): add Boox apps
2024-08-05 10:06:25 +02:00
himazawa
0fc6166b40 chore: removed typo 2024-08-04 23:59:36 +02:00
himazawa
0a7cb0d5f0 fix: fixed description 2024-08-04 23:57:42 +02:00
himazawa
c894f469ba feat: added Onyx Boox apps 2024-08-02 21:00:12 +02:00
Anonymoussaurus
bd486ea21d
Merge pull request #567 from Universal-Debloater-Alliance/fix-broken-list
fix(uad_lists): add missing quotes
2024-07-28 15:26:54 +02:00
Anonymoussaurus
9cad1db3f3
fix(uad_lists): add missing quotes 2024-07-28 15:22:04 +02:00
Anonymoussaurus
4b5a079288
Merge pull request #566 from Etienne-bdt/main
pkg(com.google.android.pixelnfc): improve description
2024-07-28 14:55:48 +02:00
EtiN7
4edca0678c
Small corrections 2024-07-28 19:41:38 +09:00
EtiN7
8105eb788b
Update uad_lists.json 2024-07-28 17:41:44 +09:00
Anonymoussaurus
f6e3c1b9b1
Merge pull request #561 from anuraggr/patch-1
pkg(com.google.android.googlequicksearchbox): improve description
2024-07-24 12:14:52 +02:00
anuraggr
15d0ae7a9e
Extend description for com.google.android.googlequicksearchbox 2024-07-23 19:21:02 +05:30
Anonymoussaurus
0209d28ddf
build(release): add testing label 2024-07-12 18:14:55 +02:00
Rudxain
4c0615ad1b build(clippy): warn pedantic group 2024-07-11 13:53:31 -04:00
Rudxain
20683fa6c4 build(lint): forbid undocumented_unsafe_blocks 2024-07-11 13:45:04 -04:00
Rudxain
6a456c278d refactor(lint): deny string_to_string, and fix errors 2024-07-11 13:40:38 -04:00
Rudxain
8b8a6c8f4b build(lint): warn shadow_unrelated 2024-07-11 13:27:44 -04:00
Rudxain
a070d1f179 build(lint): warn panic_in_result_fn 2024-07-11 13:19:31 -04:00
Rudxain
9948472c41 build(lint): warn mem_forget 2024-07-11 13:15:28 -04:00
Rudxain
d7f7d98c8f build(lint): warn large_include_file 2024-07-11 13:10:33 -04:00
Rudxain
6e52a3d554 build(lint): warn infinite_loop 2024-07-11 12:57:26 -04:00
Rudxain
fdaeb2368d build(lint): warn format_push_string 2024-07-11 12:54:54 -04:00
Rudxain
82223608d8 build(lint): deny exit 2024-07-11 12:53:18 -04:00
Rudxain
c0f2ea5beb chore(widgets): unreachable -> expect 2024-07-11 12:25:17 -04:00
Rudxain
ae2cf07fc5 chore(widgets): assume Layouts must have at least 1 child 2024-07-11 12:25:17 -04:00
Rudxain
b01d310601 chore(gui): expect selected_device rather than unwrap 2024-07-11 12:25:17 -04:00
Rudxain
1915ea04f4 refactor(gui): fix 1 unwrap lint warning 2024-07-11 12:25:17 -04:00
Rudxain
897b658d14 docs(lint): unsafe should stay as deny 2024-07-11 12:25:17 -04:00
Ricardo Fernández Serrata
3b10ea4bcb build(cargo): deny unsafe, warn unwrap 2024-07-11 12:25:17 -04:00
Frigyes
55833e9d60
Merge pull request #552 from Universal-Debloater-Alliance/chore/sys-template
chore(bug-template): Include OS, WM, and DE
2024-07-11 08:11:22 +00:00
Ricardo Fernández Serrata
1d5c1d2364
chore(bug-template): DE is not required 2024-07-10 19:10:04 -04:00
Ricardo Fernández Serrata
bae253bb29
chore(bug-template): Include OS, WM, and DE 2024-07-10 19:08:03 -04:00
Anonymoussaurus
c4abc241e7
Merge pull request #525 from Obegg/SM-A307FN-unlisted
pkg(samsung): add packages
2024-07-10 20:14:40 +02:00
Obegg
178a575d54 fix typo 2024-07-10 20:22:24 +03:00
Frigyes Erdosi Szucs
f6a1c11566
release(versioning): bumped uad-ng version and updated dependencies 2024-07-10 18:22:12 +02:00
Frigyes
2bfdb10c01
Merge pull request #531 from Rudxain/feature/auto_theme
feat(theme): follow system theme by default
2024-07-10 15:49:37 +00:00
Frigyes Erdosi Szucs
ff150c372a
refactor(theme): dark_light has exhaustive list of states 2024-07-09 10:31:34 +02:00
blitziak
33f910c048
Update uad_lists.json
my check apps there
2024-07-08 19:23:34 +00:00
Rudxain
0dda83a6f1 docs(theme): update comment about default (#540) 2024-07-08 13:49:46 -04:00
Rudxain
e40951eec5 refactor(theme): string_to_theme is more correct 2024-07-08 13:43:48 -04:00
Rudxain
ae4d56d6ba chore(theme): move Auto to 0th position 2024-07-08 13:27:41 -04:00
Frigyes Erdosi Szucs
d2098d3050
feat(theme): set theme to auto by default 2024-07-08 15:28:43 +02:00
Frigyes Erdosi Szucs
76aba1e548
Auto by default 2024-07-08 13:13:51 +02:00
Anonymoussaurus
6c1c530e8e
Merge pull request #535 from Universal-Debloater-Alliance/NoBootloopAppsMiui
pkg(miui): change descriptions and removals based on potential bootloop
2024-07-05 17:46:52 +02:00
blitziak
2cda1265c8
Apps on Miui that not cause bootloop after remove
Removing Security apps not brick deep sleep, but doing anything on phone feels like more drain battery than before.
2024-07-05 10:30:21 +00:00
edgy-b
6da6cd1b15
Merge pull request #533 from Rudxain/hotfix/settings-regression
hotfix(settings): patch regression and refactor a bit
2024-07-04 21:04:12 +00:00
Rudxain
7855b9f355 fix: revert accidental local change 2024-07-04 16:28:09 -04:00
Rudxain
2e44eefef5 refactor(User): no borrows, because Copy 2024-07-04 16:22:05 -04:00
Rudxain
2620c89302 fix(settings): 2nd attempt: mixed solution 2024-07-04 12:36:19 -04:00
Rudxain
bd5cec5c74 docs(backup): fn comment should be doc
resolves https://github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation/pull/527#discussion_r1664898648
2024-07-04 11:47:59 -04:00
Rudxain
f950156527 fix(settings): 1st attempt: moved data deps to condition 2024-07-04 11:37:37 -04:00
Rudxain
5f43725ac4 fix(config): Use actual Theme::default rather than "Dark" 2024-07-04 08:22:15 -04:00
Rudxain
72bf6fa08b feat(theme): Add Auto enum variant 2024-07-04 07:09:53 -04:00
Adhiraj S. Chauhan
e500d50068
Merge pull request #527 from Universal-Debloater-Alliance/feat/export-packages
feat(backup): add ability to export uninstalled packages with their description
2024-07-03 10:28:23 +05:30
Ed B
4e954c0624 feat(backup): add ability to export uninstalled packages with their description
- changed export file to csv

 - silenced clippy error for now (dead code), until fixed or found solution
2024-07-03 00:57:12 +03:00
Anonymoussaurus
4c4b78044f
Merge pull request #528 from alvinkim101/change-description-and-removal-for-com.lge.ims
pkg(com.lge.ims): change description and removal
2024-07-01 09:05:00 +02:00
Alvin Kim
ab56e2c89e pkg(com.lge.ims): change description and removal 2024-06-30 16:13:24 -07:00
Ed B
38522e0579 feat(backup): add ability to export uninstalled packages with their description
- fixed some deepsource issues
2024-06-30 23:30:05 +03:00
Obegg
c461df3c3a 4 unlisted packages are oem 2024-06-30 15:33:54 +03:00
Obegg
de8bd2e0a7 placeholder for 4 new unlisted packages 2024-06-30 15:27:31 +03:00
Anonymoussaurus
2de6e730ad
Merge pull request #524 from ngocanhtve/ngocanhtve-patch-1
pkg(sony): add packages
2024-06-29 13:16:35 +02:00
ngocanhtve
2cbc35948b
Update uad_lists.json
Add 3 pre-installed packages on Sony Xperia AU network
2024-06-28 10:05:55 +07:00
Anonymoussaurus
e8ea46da48
Merge pull request #503 from Universal-Debloater-Alliance/487-pkgcomhuaweiandroidinternalapp-removing-breaks-the-share-function-in-many-applications
pkg(com.huawei.android.internal.app): add note about sharing function
2024-06-27 17:52:46 +02:00
Anonymoussaurus
42cec15a7a
Merge pull request #504 from Universal-Debloater-Alliance/491-pkgscope-miuisystemuiplugin
pkg(miui.systemui.plugin): add note about breaking reboot menu
2024-06-27 17:52:32 +02:00
Anonymoussaurus
d9524e689a
Merge pull request #522 from Obegg/oneplus.config
docs(com.oneplus.config): change description
2024-06-26 21:13:28 +02:00
Obegg
b83619f08a
docs(com.oneplus.config): 'Tips & Support' will be removed. 2024-06-26 20:27:49 +03:00
Anonymoussaurus
83a832a39a
Merge pull request #512 from jxdv/pkg-adaptive-brightness
pkg(samsung): add com.samsung.android.adaptivebrightnessgo
2024-06-24 20:12:45 +02:00
jxdv
87f7976dfe update list 2024-06-24 20:02:38 +02:00
jxdv
aa8840311b add com.samsung.android.adaptivebrightnessgo 2024-06-23 16:23:22 +02:00
Anonymoussaurus
b4b160a145
pkg(com.huawei.android.internal.app): add crashing to description 2024-06-13 21:18:27 +02:00
Anonymoussaurus
ee4db0c62b
Merge pull request #505 from jxdv/update-pkg
pkg(com.motorola.att.phone.extensions): update description
2024-06-11 21:00:00 +02:00
jxdv
8f67e33ada update description 2024-06-11 20:47:19 +02:00
jxdv
05dfeedd79
Merge branch 'main' into update-pkg 2024-06-11 18:45:43 +00:00
Anonymoussaurus
aa153cb6ad
Merge pull request #506 from jxdv/update-motorola-pkg
pkg(com.motorola.VirtualUiccPayment): update description
2024-06-11 20:40:42 +02:00
Anonymoussaurus
81ea79237e
Merge pull request #489 from mirko93s/main
pkg(lg): add missing packages
2024-06-11 20:38:41 +02:00
jxdv
48b7496d54 update description of com.motorola.VirtualUiccPayment 2024-06-11 20:24:05 +02:00
jxdv
6ac7fbfaca update description of com.motorola.att.phone.extensions 2024-06-11 20:14:33 +02:00
mirko93s
ab3077101e
Update uad_lists.json 2024-06-11 17:36:10 +02:00
mirko93s
05f5f24aff
Merge branch 'Universal-Debloater-Alliance:main' into main 2024-06-11 17:33:57 +02:00
Anonymoussaurus
29e57a4bdf
Merge pull request #502 from M0-7/main
pkg(sony): raise removal level of Android TV packages
2024-06-10 17:36:28 +02:00
Anonymoussaurus
84f143bc17
pkg(miui.systemui.plugin): distinguish breakage between MIUI and HyperOS users 2024-06-10 17:29:25 +02:00
M0-7
8fa40248bc Apply suggestions from code review 2024-06-10 16:28:54 +01:00
Anonymoussaurus
133a60249a
pkg(miui.systemui.plugin): add note about breaking reboot menu 2024-06-10 17:25:22 +02:00
Anonymoussaurus
6d3e6ab7d3
pkg(com.huawei.android.internal.app): add note about sharing function 2024-06-10 17:23:08 +02:00
M0-7
cfc6ac5671
Merge branch 'main' into main 2024-06-10 15:10:55 +01:00
M0-7
b6b73c22f3 Raise removal level of some packages which caused issues 2024-06-10 15:05:50 +01:00
mirko93s
9578de14b6
Merge branch 'main' into main 2024-06-08 12:50:25 +02:00
Anonymoussaurus
06fbeb4f75
Merge pull request #424 from Universal-Debloater-Alliance/398-galaxy-app-fc-popup-ui
pkg(samsung): add warning to descriptions
2024-06-04 13:46:42 +02:00
Anonymoussaurus
1065084b6d
Merge pull request #498 from M0-7/main
pkg(sony): add packages of Android TV
2024-06-03 19:06:36 +02:00
M0-7
4d8c0e0c05 Change browser description and removal level 2024-06-03 17:53:47 +01:00
M0-7
e857158331 Apply suggestions from code review 2024-06-03 17:07:52 +01:00
M0-7
f8369ea6e2 Incorporate improvements 2024-06-03 16:24:35 +01:00
M0-7
cdbd44ca6e Add some more apps 2024-06-03 15:31:33 +01:00
M0-7
2664db85e7 Add some unlisted Sony and other packages 2024-06-03 15:06:16 +01:00
Adhiraj S. Chauhan
c814057ee7
Merge pull request #497 from Universal-Debloater-Alliance/ci/fix-workflow-not-running-in-certain-scenarios
build(ci): fix ci not running for user-submitted PR
2024-06-03 16:23:19 +05:30
Anonymoussaurus
eff8796839
build(ci): fix ci not running for user-submitted PR 2024-06-03 10:14:18 +02:00
Anonymoussaurus
5e2aae9095
Merge pull request #495 from shimeoki/patch-1
pkg(com.android.camera): fix typos in description
2024-06-02 20:55:53 +02:00
Anonymoussaurus
18c479ab21
Merge pull request #496 from jxdv/add-samsung-pkg
pkg(com.samsung.samsungpssdplus): add Samsung Magician
2024-06-02 20:54:34 +02:00
jxdv
9b547a2b62 add pkg com.samsung.samsungpssdplus 2024-06-02 15:15:30 +02:00
Anonymoussaurus
355f56fab8
Merge pull request #492 from jxdv/pkgs-desc-update
pkg(samsung / qualcomm): update descriptions
2024-06-02 14:35:33 +02:00
shimeoki
422d208182
fix(uad_lists): typos in com.android.camera
also some styling, like \n before link
2024-06-02 13:58:36 +03:00
jxdv
ae59dcfbb8 update com.samsung.android.dck.timesync pkg description 2024-06-01 15:16:03 +02:00
jxdv
33a04ad15d update com.qualcomm.qti.securemsm.mdtp pkg description 2024-06-01 15:15:34 +02:00
Anonymoussaurus
fd8b777312
Merge pull request #484 from Universal-Debloater-Alliance/479-pkg-change-description-of-comqualcommtimeservice-and-comgoogleandroidconfigupdater
pkg: improve description and change removal of com.qualcomm.timeservice and com.google.android.configupdater
2024-05-31 00:08:41 +02:00
Anonymoussaurus
24c1c9409c
pkg(samsung): change removal and improve description 2024-05-30 21:02:30 +02:00
Anonymoussaurus
eb92af334f
Merge branch 'main' into 398-galaxy-app-fc-popup-ui 2024-05-30 20:55:13 +02:00
mirko93s
f7dae28726
added some missing LG apps 2024-05-30 17:52:48 +02:00
Anonymoussaurus
359289a96f
pkg: improve description and change removal 2024-05-28 18:49:00 +02:00
Anonymoussaurus
c2c029023d
Merge pull request #482 from Universal-Debloater-Alliance/480-pkgscope-comsamsungandroiddbsc-samsung-being-samsung
pkg(samsung): add com.samsung.android.dbsc
2024-05-27 23:05:09 +01:00
Anonymoussaurus
11ccc231e5
pkg(samsung): add com.samsung.android.dbsc 2024-05-27 23:31:13 +02:00
Anonymoussaurus
4e6ea38f2d
Merge pull request #481 from Universal-Debloater-Alliance/468-pkgscope-mephhtrebleapp
pkg(me.phh.treble.app): add package for GSI ROM
2024-05-27 21:31:06 +01:00
Anonymoussaurus
ad0d480fac
pkg(com.android.settings.os.overlay): remove duplicate 2024-05-27 20:47:50 +02:00
Anonymoussaurus
589ecbb915
pkg(me.phh.treble.app): add package for GSI ROM 2024-05-27 20:46:36 +02:00
Anonymoussaurus
cbd58d5341
Merge pull request #478 from Universal-Debloater-Alliance/TECNO-Packages
pkg(tecno): add Tecno packages and change descriptions/removals of other packages
2024-05-27 17:14:09 +01:00
blitziak
9925a766bb
Update uad_lists.json 2024-05-27 14:55:20 +00:00
blitziak
493192a9a7
some must to do changes 2024-05-26 14:07:58 +00:00
blitziak
ec7635633a
Update uad_lists.json 2024-05-25 21:00:10 +00:00
blitziak
dd8541d189
Add TECNO Packages and #476, #443
Not big PR, so #476, #443 added here.
2024-05-25 00:21:24 +00:00
Anonymoussaurus
928ac3032d
Merge pull request #473 from Universal-Debloater-Alliance/issues-fix-and-new-packages
pkg: add packages, fix descriptions from issues section and from discord
2024-05-21 22:27:08 +01:00
blitziak
d9044c03d7
Update uad_lists.json 2024-05-21 21:23:27 +00:00
blitziak
0f8f25bd23
Update uad_lists.json 2024-05-21 20:05:25 +00:00
blitziak
1b0b24c55e
add packages, fix descriptions from issues section and from discord
issues #299, #450, #454, #461, #464, #465, #467 and "com.samsung.android.globalpostprocmgr", "com.samsung.android.audiomirroring", "com.aura.jet.att", "com.aura.oobe.att" from discord
2024-05-21 19:58:45 +00:00
Anonymoussaurus
bf88bd0b90
Merge pull request #472 from Universal-Debloater-Alliance/add-oneplus-apps
pkg(oneplus): add OnePlus package
2024-05-21 20:46:37 +01:00
Anonymoussaurus
271fd48866
pkg(com.oplus.nas): change removal and improve description 2024-05-21 21:35:38 +02:00
Anonymoussaurus
79abf25e6e
pkg(oneplus): add com.oplus.pantanal.ums package 2024-05-21 21:31:25 +02:00
Anonymoussaurus
4701422065
Merge pull request #471 from Universal-Debloater-Alliance/429-pkg-duplicate-packages-in-uad_list
pkg(samsung): remove duplicate packages
2024-05-21 20:17:07 +01:00
Anonymoussaurus
565e991364
pkg(samsung): remove duplicate packages 2024-05-21 20:46:28 +02:00
Adhiraj S. Chauhan
59a6605046
Merge pull request #470 from nozwock/win-executable-icon
feat(theming): add icon to Windows executable
2024-05-21 23:32:14 +05:30
Anonymoussaurus
5f4e9e439a
pkg(samsung): remove duplicate packages 2024-05-21 19:17:32 +02:00
nozwock
9cc1799f30
Fix file path typo in build.rs 2024-05-21 01:12:26 +05:30
nozwock
43c37d5a03
Add an icon resource to the windows executable 2024-05-21 01:12:26 +05:30
nozwock
3ccbb29cde
Add embed-resource to build deps 2024-05-21 01:12:26 +05:30
Anonymoussaurus
1eefb0159f
Merge pull request #457 from Universal-Debloater-Alliance/researchuadnglists
pkg: add packages, improve descriptions and removals
2024-05-20 19:25:27 +01:00
Frigyes
a31c7a8c50
Merge pull request #469 from Universal-Debloater-Alliance/add-Archive-link-for-Twitter
pkg(com.ape.mtbf): add Archive link for Twitter
2024-05-20 17:58:40 +00:00
blitziak
85bf9422c7
Update uad_lists.json 2024-05-20 17:47:51 +00:00
Anonymoussaurus
9bdaa62011
pkg(com.ape.mtbf): add Archive link for Twitter 2024-05-20 14:27:47 +02:00
Frigyes
0dbd9f9930
Merge pull request #466 from Universal-Debloater-Alliance/fix/incorrect-file-name-in-CI-file
fix(ci): incorrect filename being used for UAD list
2024-05-19 15:15:27 +00:00
Anonymoussaurus
6f59744bd0
fix(ci): incorrect filename being used for UAD list 2024-05-19 16:55:40 +02:00
blitziak
2655fcc7cb
Fixes of description and more researches about packages
Included things from issue #410 and huawei apps some apps move to unsafe.
Named some from list Google to Aosp, because its the same app with different name.
Required to WiFi work, apps move to Unsafe.
Incorrect name packages fixed.
Added one package from Miui OEM
Checked some Miui Unsafe or Expert apps again.
Changed removal place for some apps.
Some recommended apps to pixel phone not looks recommended (more expert, someone will need to check them). #441 #423 

Thats my big research uad_lists.json, it did not cost me a week.
2024-05-09 13:08:10 +00:00
Adhiraj S. Chauhan
622b55979a
Merge pull request #452 from Universal-Debloater-Alliance/bug/ui-visual-bugs
bug(ui): visual bugs in selection review
2024-05-08 11:02:05 +05:30
Ed B
65e78c0ffe bug(ui): visual bugs in selection review
- increased width of modal

 - adjusted some column sizes
2024-05-07 01:30:12 +03:00
Anonymoussaurus
189cf4ae39
Merge pull request #446 from Universal-Debloater-Alliance/feat/run-ci-on-list-changes
feat(ci): run the ci script on uad_list.json changes
2024-05-04 11:00:34 +02:00
edgy-b
2b9b7cb81c
Merge pull request #434 from Universal-Debloater-Alliance/feat/custom-backup
feat: add ability to customize backup folder
2024-05-04 08:33:24 +00:00
Frigyes Erdosi-Szucs
d51fe9b9c5
feat(ci): run the ci script on uad_list.json changes 2024-05-03 16:49:29 -07:00
edgy-b
bcd5df0c76
Merge pull request #435 from Universal-Debloater-Alliance/feat/readd-export-selection
feat(backup): re-add export selection to text file
2024-05-03 09:26:31 +00:00
Himadri Bhattacharjee
1193509485
Merge pull request #445 from Universal-Debloater-Alliance/core/DRY
Another house cleanup
2024-05-03 10:43:57 +05:30
Ed B
a654d2a324 Merge branch 'core/DRY' of https://github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation into core/DRY 2024-05-03 02:57:44 +03:00
Ed B
24006541b1 cargo, clippy fix 2024-05-03 02:57:04 +03:00
Ed B
0060258021 Another house cleanup
- removed unused _settings from waiting_view

 - use clone_from instead from clone https://doc.rust-lang.org/std/clone/trait.Clone.html#method.clone_from
2024-05-03 02:52:34 +03:00
Ed B
95848fb5c2 - clippy error fix 2024-05-03 01:58:39 +03:00
Ed B
064c329423 Merge remote-tracking branch 'origin' into feat/custom-backup 2024-05-03 01:27:34 +03:00
deepsource-autofix[bot]
bf1ea93082
style: format code with Rustfmt
This commit fixes the style issues introduced in 0060258 according to the output
from Rustfmt.

Details: https://github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation/pull/445
2024-05-02 21:55:08 +00:00
Himadri Bhattacharjee
22054511f6
Merge pull request #437 from Universal-Debloater-Alliance/core/DRY
core/DRY: don't repeat yourself
2024-05-02 18:55:22 +05:30
Anonymoussaurus
0855d7d93e
Merge pull request #439 from rtcms/patch-1
pkg(com.oplus.safecenter): improve description
2024-05-01 22:34:46 +02:00
RT
54cb618593
Update uad_lists.json 2024-05-01 12:41:26 -04:00
RT
678480a0d6
Update uad_lists.json 2024-04-30 16:40:48 -04:00
Ed B
2335e84c43 core/DRY: don't repeat yourself
- added wrapper function for button

 - removed Refresh style, as basically it was styled same as Primary
2024-04-30 01:29:54 +03:00
Adhiraj S. Chauhan
8c55879c40
Merge pull request #436 from Universal-Debloater-Alliance/fix-broken-JSON-list
pkg: remove bracket that breaks list
2024-04-29 19:42:37 +05:30
Anonymoussaurus
4dae79a665
pkg: remove bracket that breaks list 2024-04-29 16:02:18 +02:00
Anonymoussaurus
384a155942
Merge pull request #431 from arukateru/main
pkg(com.dti.tracfone): add description for popular carrier bloatware installer
2024-04-29 11:40:11 +02:00
Alcatel
e358ba2013
Update uad_lists.json 2024-04-29 00:46:17 -04:00
Ed B
f7ca3071f6 feat(backup): re-add export selection to text file
- added back possibility to export current selection to txt file

 - on successful export show modal
2024-04-29 02:35:14 +03:00
Ed B
7f25afc4b7 Merge conflict fix 2024-04-28 19:34:08 +03:00
Ed B
6931fb422f feat: add ability to customize backup folder
- added setting for back up folder

 - added pre-selected icons when importing icons.json to icommon

 - added Backup / Restore category when device is connected
2024-04-28 17:08:41 +03:00
Anonymoussaurus
4a3de42560
Merge pull request #433 from Universal-Debloater-Alliance/env-set-var
codecov: move serial environment variable name into constant
2024-04-28 15:06:57 +02:00
Himadri Bhattacharjee
11e386dc3c
doc: add documentation to serial env var constant 2024-04-28 10:40:02 +05:30
Himadri Bhattacharjee
39cb07a012
codecov: move serial environment variable name into constant 2024-04-28 10:33:39 +05:30
Alcatel
97d98e5dba
Update uad_lists.json 2024-04-27 01:11:52 -04:00
Anonymoussaurus
b5cd560d37
Merge pull request #430 from Universal-Debloater-Alliance/migloballayoutandrealmebootloops
Mi global layout and Realme Unsafe packages
2024-04-25 19:58:39 +02:00
Anonymoussaurus
eded82c2de
pkg(com.mi.globallayout): fix typos 2024-04-25 19:57:33 +02:00
blitziak
2fdda45355
mi global layout and realme unsafe packages
There's better description for "mi layouts apps" to Miui launcher app running on the first time and found unsafe Realme apps in the lists.
2024-04-24 19:48:11 +00:00
Himadri Bhattacharjee
9540116146
Merge pull request #428 from Universal-Debloater-Alliance/dependabot/cargo/rustls-0.22.4
build(deps): bump rustls from 0.22.2 to 0.22.4
2024-04-23 08:34:57 +05:30
dependabot[bot]
429399f91a
build(deps): bump rustls from 0.22.2 to 0.22.4
Bumps [rustls](https://github.com/rustls/rustls) from 0.22.2 to 0.22.4.
- [Release notes](https://github.com/rustls/rustls/releases)
- [Changelog](https://github.com/rustls/rustls/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rustls/rustls/compare/v/0.22.2...v/0.22.4)

---
updated-dependencies:
- dependency-name: rustls
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-19 19:48:21 +00:00
Anonymoussaurus
5c80fb83e1
Merge pull request #427 from l-theanine/main
added new transsion packages
2024-04-19 20:38:23 +02:00
l-theanine
36fa2003c7 added new transsion packages
added info about these packages ->

com.transsion.manualguide
com.transsion.aiwallpaper
com.transsion.aivoiceassistant
com.transsion.aisettings
2024-04-19 18:10:52 +05:30
Anonymoussaurus
7d879b3d04
Merge pull request #426 from l-theanine/main
pkg(com.facemoji.lite.transsion): add info about potential breakage on Infinix phones
2024-04-19 12:42:07 +02:00
l-theanine
a28dee26f8 fix some typos 2024-04-19 15:53:04 +05:30
l-theanine
2787754c43 warning about potential breakage on infinix
fix according to suggestions
2024-04-19 15:47:42 +05:30
l-theanine
8b2d71136b
Warning about potential breakage on infinix phones 2024-04-17 05:49:00 +05:30
Frigyes
053f1eee0d
Merge pull request #422 from Universal-Debloater-Alliance/cyclomatic-complexity
refactor: reduce cycolmatic complexity
2024-04-16 06:24:42 +00:00
Anonymoussaurus
e9f97fc244
Merge pull request #425 from Universal-Debloater-Alliance/420-pkg-comrealmeasmusic
pkg(com.realme.as.music): add package
2024-04-15 17:57:52 +02:00
Anonymoussaurus
9aa26dadd3
pkg(com.realme.as.music): add package 2024-04-15 12:38:50 +02:00
Anonymoussaurus
a15ac1ad39
pkg(samsung): add warning to descriptions 2024-04-13 13:51:29 +02:00
Himadri Bhattacharjee
8df133c703
Merge pull request #416 from Universal-Debloater-Alliance/feat/upload-test-coverage-to-DeepSouce-in-CI
feat(ci): run test coverage in CI and upload to DeepSource
2024-04-13 10:01:37 +05:30
Himadri Bhattacharjee
80edde756b
refactor: move the ready state view, control panel and error modal into their own functions 2024-04-13 09:40:16 +05:30
Frigyes
9b82148f5d
Merge pull request #409 from Universal-Debloater-Alliance/show-adb-error
feat: graphically display error when adb command fails
2024-04-12 13:40:15 +00:00
Himadri Bhattacharjee
2948d5e1c5
docs: add doc comment for adberror 2024-04-12 18:33:57 +05:30
Himadri Bhattacharjee
8001609bbd
fix: remove unnecessary comment 2024-04-12 18:29:52 +05:30
Anonymoussaurus
1a78cfe3c9
Merge pull request #402 from Universal-Debloater-Alliance/Samsung+Pending
pkg(samsung): add Samsung packages and improve documentation of some others
2024-04-12 13:07:16 +02:00
Himadri Bhattacharjee
7ab6f39ab6
Merge branch 'main' into show-adb-error 2024-04-12 10:46:40 +05:30
Himadri Bhattacharjee
898f815963
feat: add scrollbar to the error text 2024-04-12 10:45:09 +05:30
blitziak
bc74fa1e54
ChangesAndFinallyMerge 2024-04-11 20:33:38 +00:00
“Frigyes06”
e955dadfdb
fix(ci): make new CI script actually work 2024-04-09 13:45:08 -07:00
“Frigyes06”
30161d820b
feat(ci): new job w/ test coverage and upload 2024-04-09 13:08:49 -07:00
Anonymoussaurus
75287baa36
Merge pull request #413 from Universal-Debloater-Alliance/ci/upload-artifacts-correclty
fix(ci): upload artifacts correctly
2024-04-09 21:31:35 +02:00
Anonymoussaurus
01209d4577
Merge pull request #414 from Universal-Debloater-Alliance/fix/exclude-windows-console-entirely-on-non-windows-systems
feat(app): exclude windows terminal attach
2024-04-09 19:55:49 +02:00
Frigyes
e86c3f7891
Capitalization fixes
Co-authored-by: Anonymoussaurus <50231698+AnonymousWP@users.noreply.github.com>
2024-04-09 09:20:36 -07:00
Frigyes
2fe88e68c0
Fixed typos 2024-04-09 08:31:03 -07:00
“Frigyes06”
3869bfc59a
feat(app): added a bot of docs and one test 2024-04-08 13:59:39 -07:00
deepsource-autofix[bot]
13a928a6e2
style: format code with Rustfmt
This commit fixes the style issues introduced in 6ed6c1f according to the output
from Rustfmt.

Details: https://github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation/pull/414
2024-04-08 20:25:06 +00:00
“Frigyes06”
6ed6c1f36e
fix(app): exclude windows terminal attach 2024-04-08 13:23:34 -07:00
Frigyes Erdosi-Szucs
018f115d94
Fixed artifact paths 2024-04-07 21:58:15 -07:00
Frigyes
45b22318c1
Merge pull request #411 from Universal-Debloater-Alliance/deepsource-config-f20a0980
ci: update .deepsource.toml
2024-04-07 18:49:20 +00:00
Anonymoussaurus
f7837f3d98
Merge pull request #412 from Universal-Debloater-Alliance/feat(docs)/add-deepsource-badges-to-readme
docs(readme): add DeepSource badges
2024-04-06 19:09:29 +02:00
Frigyes
94d9e77519
Merge pull request #399 from Universal-Debloater-Alliance/fix-typos-in-UAD-ng
style: remove redundant spaces and fix misc typos
2024-04-06 14:56:17 +00:00
“Frigyes06”
3613af51cd
fix(app): line break 2024-04-05 14:07:33 -07:00
“Frigyes06”
f5b9d62778
feat(docs): added DeepSource badges to README.md 2024-04-05 13:49:36 -07:00
deepsource-autofix[bot]
d54df7c38e
ci: update .deepsource.toml 2024-04-05 20:38:27 +00:00
Anonymoussaurus
e066e1809d
Merge pull request #408 from Universal-Debloater-Alliance/404-docsreadme-add-matrix-link
docs(readme): add Matrix link
2024-04-05 17:43:28 +02:00
Anonymoussaurus
4ddc0b6cf7
docs(readme): fix incorrect embed of image 2024-04-04 17:55:50 +02:00
Anonymoussaurus
78ff8d075c
docs(readme): use Matrix logo 2024-04-04 17:45:49 +02:00
Anonymoussaurus
282ec9b691
Merge pull request #407 from Universal-Debloater-Alliance/403-comsecknoxswitcher
pkg(com.sec.knox.switcher): add package
2024-04-03 22:47:59 +02:00
Anonymoussaurus
89ec418f82
Merge pull request #405 from Universal-Debloater-Alliance/392-pkgcomandroidphone-add-to-description
pkg(com.android.phone): change description and removal
2024-04-03 20:17:31 +02:00
Anonymoussaurus
3a5971749f
Merge pull request #406 from Universal-Debloater-Alliance/393-comvzwhssmyverizon
pkg(com.vzw.hss.myverizon): change description
2024-04-03 20:17:21 +02:00
Anonymoussaurus
261d7bba33
docs(readme): add Matrix link 2024-04-03 14:29:53 +02:00
Anonymoussaurus
5faf5f1804
pkg(com.sec.knox.switcher): add package 2024-04-03 14:17:28 +02:00
Anonymoussaurus
23c021c431
pkg(com.vzw.hss.myverizon): change description 2024-04-03 14:11:31 +02:00
Anonymoussaurus
2e5c2aa0b8
pkg(com.android.phone): change description and removal 2024-04-03 14:03:24 +02:00
Himadri Bhattacharjee
2a2bfd182d
feat: graphically display error when adb command fails 2024-04-03 08:57:23 +05:30
blitziak
eb3af17d07
Samsung More Packages + Pending Packages
Some Pending Packages Explained, Added more unlisted apps.
2024-04-02 17:55:19 +00:00
Anonymoussaurus
f6e46450f4
fix(ci): shorten line to fix issue 2024-04-02 19:22:49 +02:00
Anonymoussaurus
ad9297dca0
Merge pull request #395 from Universal-Debloater-Alliance/replace-nitter-link
pkg: replace Nitter URLs
2024-04-02 11:50:08 +02:00
Anonymoussaurus
04611d710b
Merge pull request #397 from Universal-Debloater-Alliance/330-mipad-kitkat-home-and-recent-buttons-stopped-working-after-removing-recommended-+-2-other-packages
pkg(com.android.keyguard): add warning for Mi Pad
2024-04-02 11:49:53 +02:00
Anonymoussaurus
47e866bd0f
style: don't capitalise wording 'About' screen 2024-04-01 17:55:09 +02:00
Anonymoussaurus
d7eb48657f
style: replace word 'Documentation' 2024-04-01 17:52:18 +02:00
Anonymoussaurus
e60aba0452
style: improve wording unsafe package removal 2024-04-01 17:51:48 +02:00
Anonymoussaurus
b48ac872cc
style: remove redundant spaces and fix misc typos 2024-03-31 13:15:36 +02:00
Anonymoussaurus
4eb4fc9060
pkg(com.android.keyguard): add warning for Mi Pad 2024-03-30 19:43:30 +01:00
Anonymoussaurus
2c12e8e952
pkg: replace Nitter URLs 2024-03-29 20:51:15 +01:00
Anonymoussaurus
5ae2ed405d
Merge pull request #382 from Universal-Debloater-Alliance/381-replacement-of-dead-nitter-links
pkg(descriptions): replace Nitter URL by Archive.org URL
2024-03-28 20:07:32 +01:00
Anonymoussaurus
b77dd8b71c
Merge pull request #387 from Universal-Debloater-Alliance/384-pkgscope-comqualcommqtilbtdsda-breaks-switching-audio-output-during-phone-calls
pkg(com.qualcomm.qtil.btdsda): change description and removal
2024-03-28 20:06:27 +01:00
Anonymoussaurus
61bddf711d
Merge pull request #388 from Universal-Debloater-Alliance/385-pkgscope-comqtiqualcommdatastatusnotification-breaks-mobile-networks-section-and-sims-lose-network-in-hyperos
pkg(com.qti.qualcomm.datastatusnotification): change description and removal
2024-03-28 20:06:07 +01:00
Anonymoussaurus
8f6a857fc0
Merge pull request #391 from MayankSharma-dev/new-package-HeyTap-Melody(Oppo)
Update uad_lists.json
2024-03-28 15:22:49 +01:00
Anonymoussaurus
190942c67f
pkg(com.heytap.headset): change removal 2024-03-28 15:20:53 +01:00
Mayank Sharma
7bffd15dff Update uad_lists.json
uad update list [HeyTap Melody(Oppo)]
2024-03-28 19:46:04 +05:30
Anonymoussaurus
eb2e0fb15a
pkg(com.qti.qualcomm.datastatusnotification): change description and removal 2024-03-28 00:24:10 +01:00
Anonymoussaurus
bef938ad8e
pkg(com.qualcomm.qtil.btdsda): change description and removal 2024-03-27 23:28:47 +01:00
Anonymoussaurus
9607176475
pkg(descriptions): replace Nitter URL by Archive.org URL 2024-03-26 17:36:41 +01:00
Anonymoussaurus
bf15806cc9
Merge pull request #379 from Universal-Debloater-Alliance/1.0.3-release-prep
chore(release-preparation): update dependencies
2024-03-25 14:37:07 +01:00
“Frigyes06”
34ea50de5a
bumped dependencies 2024-03-25 06:27:29 -07:00
Frigyes
9def319125
Merge pull request #373 from edgy-b/bug/selected-packages
fix(ui): toggle all checkboxes and review button is not updated on selected device
2024-03-25 13:17:24 +00:00
Frigyes
fb04a25291
Merge pull request #372 from Universal-Debloater-Alliance/bug/update-check
fix(update-check): when downloading an update failed, UAD-ng isn't verbose about it
2024-03-24 15:45:25 +00:00
Anonymoussaurus
26e182e4e8
Merge pull request #368 from Universal-Debloater-Alliance/Change-pending-list-to-anything-else
pkg: add many packages to list (before pending)
2024-03-23 15:40:03 +01:00
Ed B
d5b6a135c8 bug(ui): toggle all checkbox and review button is not updated on selecting device
- messed up placement correct placement, now it fixed toggle
2024-03-23 16:04:21 +02:00
Ed B
c074a22355 bug(update-check): when dowloading an update failed, UAD-ng isn't verbose about it 2024-03-23 14:52:28 +02:00
Ed B
67d13f140d Merge remote-tracking branch 'origin' into bug/update-check. Merge conflict fix 2024-03-23 14:44:41 +02:00
Ed B
5fc63cca5c bug(update-check): when dowloading an update failed, UAD-ng isn't verbose about it
- removed todo in sync.rs, ADB verbose message is implemented

 - added message to display if update failed with button to go back

 - added button for ADB failed view with link to wiki page

 - tweaked waiting_view fn
2024-03-23 14:40:27 +02:00
Anonymoussaurus
7750a19abd
Merge pull request #371 from Universal-Debloater-Alliance/bug/uad_list
bug(uad-list): json parsing error
2024-03-23 12:06:51 +01:00
Ed B
fa5240f70d bug(uad-list): json parsing error
- fmt check fix
2024-03-23 12:29:23 +02:00
Ed B
1c85948049 bug(uad-list): json parsing error
- remove part of code worked on issue for updating app
2024-03-23 12:22:38 +02:00
Ed B
eeca54b7bb bug(uad-list): json parsing error
- fixed json file
2024-03-23 12:19:17 +02:00
Frigyes
a440f3d2fc
Merge pull request #364 from edgy-b/bug/logo
fix(theming): logo not visible on Windows 11 light mode
2024-03-23 03:30:04 +00:00
Ed B
10dc650a74 fix(theming): logo not visible on Windows 11 light mode
- naming adjustments
2024-03-23 04:21:56 +02:00
Frigyes
0f9ba4693e
Merge pull request #369 from Universal-Debloater-Alliance/refactor/use-if-else-for-booleans
refactor(app): use if-else instead of match over booleans
2024-03-23 01:58:21 +00:00
Anonymoussaurus
c757f1a506
Merge pull request #367 from Universal-Debloater-Alliance/Blitz517-patch-1
pkg: add Xiaomi packages and improve documentation/removals of some other packages
2024-03-22 19:20:07 +01:00
Anonymoussaurus
1a20417081
pkg: improve wording 2024-03-22 19:19:28 +01:00
blitziak
07759732fa
changes 2024-03-22 17:58:49 +00:00
Frigyes Erdosi-Szucs
d8e20b522e
refactor(app): remove redundant code 2024-03-22 10:19:53 -07:00
Frigyes Erdosi-Szucs
ee6994f524
refactor(app): formatting fix 2024-03-22 10:05:19 -07:00
Frigyes Erdosi-Szucs
d5fb9d546e
refactor(app): Use if-else instead of match over booleans 2024-03-22 09:53:11 -07:00
Anonymoussaurus
78ebb7c2c5
pkg: add many packages to list 2024-03-22 15:16:23 +01:00
blitziak
44be2a1670
Xiaomi more packages / changes
more information, less disinformation
2024-03-21 13:05:06 +00:00
Adhiraj S. Chauhan
4e88658094
Merge pull request #366 from Universal-Debloater-Alliance/354-docscontributing-improve-release-management
docs(contributing): improve release management
2024-03-21 05:20:11 +05:30
Anonymoussaurus
4089a8e36a
docs(contributing): add semantic versioning header 2024-03-20 20:25:43 +01:00
Anonymoussaurus
7b15cb5919
docs(contributing): add release management header 2024-03-20 20:04:39 +01:00
Anonymoussaurus
c5848c91e6
docs(changelog): remove changelog 2024-03-20 19:58:20 +01:00
Frigyes
1580e25a2d
Merge pull request #365 from Universal-Debloater-Alliance/streamline-wiki-with-readme
docs(readme): clarify what the Wiki is used for
2024-03-19 21:02:04 +00:00
Anonymoussaurus
5b5afe5a64
docs(readme): clarify what the Wiki is used for 2024-03-19 21:36:16 +01:00
Anonymoussaurus
7e155c396f
Merge pull request #362 from Universal-Debloater-Alliance/356-pkgcnwpsmoffice_eng-wps-office-suite
pkg(xiaomi): add packages
2024-03-19 16:46:54 +01:00
Adhiraj S. Chauhan
9459a3e1c4
Merge pull request #340 from edgy-b/feat/settings-icon
feat(ui): "iconify" Settings button
2024-03-19 15:47:01 +05:30
Ed B
da197e219b feat(ui): "iconify" Setting button
- reverted back refresh button look

 - changed settings button icon
2024-03-19 12:00:46 +02:00
Adhiraj S. Chauhan
7883e2f3cb
Merge pull request #348 from edgy-b/feat/adb-inform
fix(startup): refreshing doesn't make the "adb not installed" message disappear
2024-03-19 05:46:43 +05:30
Ed B
e74e9c82ac bug(uad-ng): logo not visible on Windows 11 light mode
- fix mixed up logo (should be vice versa) not same
2024-03-18 23:00:54 +02:00
Ed B
cfa9011906 bug(uad-ng): logo not visible on Windows 11 light mode
- added logo dark logo
2024-03-18 21:34:52 +02:00
Anonymoussaurus
f549d33855
pkg(xiaomi): add com.xiaomi.aicr 2024-03-18 19:33:31 +01:00
Anonymoussaurus
57d9cdd50b
pkg(xiaomi): add cn.wps.moffice_eng 2024-03-18 18:47:14 +01:00
Frigyes
a6ee1c3e63
Merge pull request #344 from edgy-b/feat/no-self-update
fix(app): unused variable 'res' when building with no-self-update
2024-03-18 15:18:11 +00:00
Anonymoussaurus
400a88d84f
Merge pull request #337 from qumuq-til/patch-2
docs(readme): specify user's expectations what UAD-ng users can and cannot do
2024-03-18 15:39:42 +01:00
qumuq-til
a07c7eb3dd
Update README.md
Agreed with the changes

Co-authored-by: Anonymoussaurus <50231698+AnonymousWP@users.noreply.github.com>
2024-03-18 17:33:14 +03:00
qumuq-til
d7bbed124d
Merge branch 'main' into patch-2 2024-03-18 17:22:14 +03:00
Ed B
054796024b feat(ui): "iconify" Setting button
- reduced window size
2024-03-18 12:09:04 +02:00
edgy-b
4a947e0bfb
Merge branch 'main' into feat/settings-icon 2024-03-18 09:57:42 +00:00
edgy-b
f643f1dacf
deps(iced): upgrade iced to 0.12 (#331)
* feat: iced-12

 - upgraded to iced 12

 - fixed white theme dropdown selector color

* feat: iced-12

 - cargo fmt check fixes

* deps(iced): upgrade iced to 0.12

 - fixed Modal and added back Position

* deps(iced): upgrade iced to 0.12

 - fmt check fixes

* feat(ui): updgrade to iced library

 - fixed Review selection modal, where text wasn't showing. Decreased size

* deps(iced): upgrade iced to 0.12

 - reverted back to use borrow

* deps(iced): upgrade iced to 0.12

* deps(iced): upgrade iced to 0.12

 - revert back version number

* deps(iced): upgrade iced to 0.12

 - added back rounded corners, removed by mistake
2024-03-18 09:50:00 +01:00
Anonymoussaurus
b3d754f3b2
Merge pull request #351 from Universal-Debloater-Alliance/350-remove-comsecandroiddiagmonagent-from-recommended-packages
pkg(com.sec.android.diagmonagent): add warning and change removal
2024-03-17 23:01:08 +01:00
Anonymoussaurus
50e3e78a63
Merge pull request #341 from Universal-Debloater-Alliance/improve-description-of-com.hoffnung
pkg(com.hoffnung): warn user to disable instead of uninstall
2024-03-17 23:00:56 +01:00
Anonymoussaurus
99a8460dce
Merge pull request #342 from Universal-Debloater-Alliance/fix-typos
pkg: fix typos
2024-03-17 23:00:45 +01:00
Anonymoussaurus
1c112ee81b
pkg(com.sec.android.diagmonagent): add warning and change removal 2024-03-17 21:49:51 +01:00
Ed B
e6c3bb8649 bug(app): inform user of ADB if not insatlled
- fix fmt linting
2024-03-17 16:47:13 +02:00
Ed B
6ae9c519bc bug(app): inform user of ADB if not insatlled
- fixed issue where if adb was installed and refresh button pressed, message about ADB not installed was still visible
2024-03-17 16:43:44 +02:00
Adhiraj S. Chauhan
6ba24f6270
Merge pull request #334 from edgy-b/bug/selected-packages
bug(ui): toggle all checkbox and review button is not updated on selecting device
2024-03-17 16:19:26 +05:30
Ed B
4d29bd40e8 feat(ui): "iconify" Setting button
- added json file

 - reimported ttf file
2024-03-17 11:18:33 +02:00
Ed B
bfbabdc666 Merge branch 'bug/selected-packages' of https://github.com/edgy-b/universal-android-debloater-next-generation into bug/selected-packages 2024-03-17 10:40:26 +02:00
Ed B
06cff88759 Merge branch 'main' into bug/selected-packages 2024-03-17 10:39:10 +02:00
Adhiraj S. Chauhan
8705fd817b
Merge pull request #343 from edgy-b/feat/adb-inform
feat(startup): inform user when ADB isn't installed
2024-03-17 06:49:38 +05:30
Ed B
f83987f1f2 bug(app): unused variable \'res\' when building wiht no-self-update
- fixed issues when feature: no-self-update flag was passed
2024-03-16 21:31:54 +02:00
Ed B
b678bff339 bug(app): unused variable \'res\' when building wiht no-self-update 2024-03-16 21:20:56 +02:00
edgy-b
f347d50843
Update src/gui/views/list.rs
Co-authored-by: Anonymoussaurus <50231698+AnonymousWP@users.noreply.github.com>
2024-03-16 18:19:55 +00:00
Ed B
9bac34748f bug(app): inform user of ADB if not insatlled
- fixed introduced bug if adb is installed and device is loading it would show ADB is not installed

 - added option to colorize text
2024-03-16 20:15:15 +02:00
Ed B
39fae0aea2 bug(app): inform user of ADB if not insatlled
- fixed introduced bug if adb is installed and device is loading it would show ADB is not installed

 - added option to colorize text
2024-03-16 20:12:16 +02:00
Ed B
cac50adcd9 bug(app): inform user of ADB if not insatlled 2024-03-16 18:53:58 +02:00
Anonymoussaurus
6190d76191
pkg: fix typos 2024-03-16 15:19:13 +01:00
Anonymoussaurus
ada01dff42
pkg(com.hoffnung): warn user to disable instead of uninstall 2024-03-16 14:34:20 +01:00
Ed B
7e58d05819 feat(ui): "iconify" Setting button
- turned Settings button into button with icon

Tooltip can be added, let me know. Don't think gear icon can be mistaken for something else than settings
2024-03-16 15:24:16 +02:00
Prakhar Baranwal
33f979ddcf
pkg: update some samsung packages (#312)
* pkg: update some samsung packages

* small fixes

* "nitpick"
2024-03-15 19:03:48 +01:00
edgy-b
02d08d50d1
Merge branch 'main' into bug/selected-packages 2024-03-14 18:19:47 +00:00
Anonymoussaurus
d60b3c4327
Merge pull request #335 from Universal-Debloater-Alliance/324-pkgcomonepluscameraservice-bootloop-on-android-14-custom-rom
pkg(com.oneplus.camera.service): add warning to description
2024-03-14 19:19:13 +01:00
Anonymoussaurus
d8b30a7f52
pkg(com.oneplus.camera.service): add notice about Android 14 2024-03-14 18:53:49 +01:00
qumuq-til
7d34061c07
Update README.md
Added important information to adjust users's expectations regarding what UAD-NG can and cannot do.
2024-03-14 15:09:58 +03:00
Anonymoussaurus
bb05703ec1
pkg(com.oneplus.camera.service): add warning to description 2024-03-14 12:06:43 +01:00
edgy-b
8049812b80
Merge branch 'main' into bug/selected-packages 2024-03-14 08:25:02 +00:00
Ed B
579a270830 bug(app): toggle all checkbox and review button is not updated on selecting device
- fixed checkbox and review button
2024-03-14 02:23:26 +02:00
Anonymoussaurus
b0348a9b3b
Merge pull request #333 from Universal-Debloater-Alliance/Blitz517-patch-1
pkg(vivo): add packages and change descriptions
2024-03-13 21:04:35 +01:00
blitziak
bfdb734481
vivo packages that not added 2024-03-13 19:58:16 +00:00
Frigyes
b73d3e7328
Merge pull request #323 from Universal-Debloater-Alliance/317-docsreadme-replace-0x-screenshot-by-1xx-screenshot
docs(readme): add screenshot of v1.0.2
2024-03-13 18:07:47 +00:00
Anonymoussaurus
77b4da2683
docs(readme): use default window size 2024-03-13 17:20:57 +01:00
Anonymoussaurus
e62419666c
Merge pull request #332 from jxdv/update-uad-list
fix: update descriptions of pkgs
2024-03-13 16:21:18 +01:00
jxdv
f0c1dae0e1 apply suggestions 2024-03-13 16:19:46 +01:00
jxdv
45848a4819 remove junk from com.samsung.android.rubin.app 2024-03-13 15:51:37 +01:00
jxdv
43443d43b4 noticable typos 2024-03-13 15:49:22 +01:00
jxdv
48c9181dbe update com.sonymobile.anondata 2024-03-13 15:47:10 +01:00
jxdv
72b6cf88f8 remove suggestion from com.sonymobile.email 2024-03-13 15:44:05 +01:00
jxdv
8082025750 update com.sonyericsson.idd.agent 2024-03-13 15:40:35 +01:00
Anonymoussaurus
68ed81bc4a
Merge pull request #318 from Universal-Debloater-Alliance/dependabot/cargo/mio-0.8.11
build(deps): bump mio from 0.8.10 to 0.8.11
2024-03-13 13:19:59 +01:00
Adhiraj S. Chauhan
03e1a5eb09
Merge pull request #311 from Universal-Debloater-Alliance/217-buildrelease-add-labels-to-current-release-workflow
release(changelog): add and remove labels
2024-03-13 17:45:25 +05:30
Anonymoussaurus
befb529fc7
release(changelog): add 'Miscellaneous' and 'Package/apps' titles 2024-03-12 23:26:38 +01:00
Anonymoussaurus
e729e98fd1
Merge pull request #322 from Universal-Debloater-Alliance/Blitz517-patch-1
pkg(huawei): add packages and change descriptions/removals
2024-03-12 23:17:57 +01:00
blitziak
052d67b0ac
requested changes have changed 2024-03-12 16:56:54 +00:00
blitziak
34b8095168 Huawei Packages, Fixes
Removed some google play links that not exist,
added packages,
changed some descriptions
2024-03-10 23:13:27 +01:00
Frigyes
b925942f71
Merge pull request #327 from Universal-Debloater-Alliance/fix-incorrect-title-placeholder
chore(issue-template): fix incorrect placeholder
2024-03-10 11:55:39 -07:00
Anonymoussaurus
20c669d215
chore(issue-template): fix incorrect placeholder 2024-03-10 19:12:33 +01:00
Anonymoussaurus
44c12cc447
Merge pull request #325 from jxdv/update-list
pkg(huawei): update descriptions
2024-03-10 19:05:43 +01:00
jxdv
beceefb18f update description 2024-03-10 17:59:07 +01:00
jxdv
bf4a7dc5cd update com.huawei.wallet 2024-03-10 15:49:18 +01:00
jxdv
d2a594c2ed update com.huawei.mycenter 2024-03-10 15:48:37 +01:00
jxdv
d01e7a4c88 update com.huawei.meetime 2024-03-10 15:47:32 +01:00
Adhiraj S. Chauhan
6729a1606a
Merge pull request #321 from edgy-b/feat/consistent-btns
feat(ui): consistent buttons placements and "update" wording
2024-03-10 14:18:42 +05:30
Anonymoussaurus
c6d195f143
docs(readme): add screenshot of v1.0.2 2024-03-09 16:16:15 +01:00
Ed B
363480cd68 feat(ui): consistent wording
- changed wording like in list.rs file. Uppercased text if device wasn't found
2024-03-06 22:23:43 +02:00
Ed B
0b38a6e033 feat(ui): Consitent buttons placements
- changed wording for update info, on small window size previous wording takes a lot of screen. Updated is not ideal, but takes less screen.
2024-03-06 22:12:11 +02:00
Ed B
cc646f1a6a feat(ui): Consitent buttons placements
- moved buttons, so that they are consistent if device is not found vs found
2024-03-06 22:01:48 +02:00
Anonymoussaurus
f3f611dbc9
Merge pull request #315 from Universal-Debloater-Alliance/313-add-more-realme-system-apps
pkg(realme): add packages and fix typo
2024-03-05 18:46:07 +01:00
dependabot[bot]
64f775e51c
build(deps): bump mio from 0.8.10 to 0.8.11
Bumps [mio](https://github.com/tokio-rs/mio) from 0.8.10 to 0.8.11.
- [Release notes](https://github.com/tokio-rs/mio/releases)
- [Changelog](https://github.com/tokio-rs/mio/blob/master/CHANGELOG.md)
- [Commits](https://github.com/tokio-rs/mio/compare/v0.8.10...v0.8.11)

---
updated-dependencies:
- dependency-name: mio
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-04 21:29:44 +00:00
Anonymoussaurus
3764132e2a
Merge pull request #314 from Universal-Debloater-Alliance/306-docscontributing-add-guidelines-for-members-and-contributors
docs(contributing): add new headers and guidelines
2024-03-04 18:48:58 +01:00
Anonymoussaurus
f3a318e9ac
docs(contributing): improve sentence release preparation 2024-03-04 16:02:05 +01:00
Anonymoussaurus
fd18abed35
release(changelog): remove unused bootloop label 2024-03-04 11:09:28 +01:00
Anonymoussaurus
621bf60604
pkg(realme): add packages and fix typo 2024-03-03 20:54:16 +01:00
Anonymoussaurus
d1095404e2
docs(contributing): add new headers and guidelines 2024-03-03 15:26:00 +01:00
Anonymoussaurus
f85ad7d102
release(changelog): add and remove labels 2024-03-02 21:26:49 +01:00
Anonymoussaurus
e0d181e409
Merge pull request #309 from Universal-Debloater-Alliance/Blitz517-patch-1
pkg: add Infinix packages
2024-03-02 21:02:45 +01:00
blitziak
fa7139628b
required changes introduced 2024-03-02 19:50:16 +00:00
blitziak
4ba71d18e2
infinix unlisted bloat XOS 10.0
Thanks to thatgreenpie for sharing unlisted bloat apk's.
2024-03-02 12:28:10 +00:00
Frigyes
4c6621d8d0
Merge pull request #296 from Universal-Debloater-Alliance/174-enhance-summary-about-comsecandroidapplauncher
pkg(com.sec.android.app.launcher): improve description
2024-02-29 11:51:41 -08:00
Frigyes
372a8899e0
Merge pull request #295 from jxdv/ci-checksum
ci: edit checksum artifact paths to allow automatic check
2024-02-29 07:01:18 -08:00
jxdv
abfaba38de
Merge branch 'main' into ci-checksum 2024-02-29 14:57:02 +00:00
Adhiraj S. Chauhan
f8788096d2
Merge pull request #307 from Universal-Debloater-Alliance/fix-issue-form-labels
chore(issue-templates): fix typos in labels
2024-02-29 15:10:40 +05:30
Anonymoussaurus
6d0d1ae6d8
chore(issue-templates): fix typos in labels 2024-02-29 10:38:03 +01:00
Anonymoussaurus
9fa5ebd483
Merge pull request #304 from xe1st/patch-2
pkg: add `com.longcheertel.secretcode`
2024-02-28 21:15:06 +01:00
xe1st
ad39df22f9 Update uad_lists.json
Update uad_lists.json
2024-02-28 23:10:44 +03:00
Frigyes
cd6ea05ff3
Merge pull request #305 from Universal-Debloater-Alliance/fix-typo-in-labels-for-issue-forms
chore(issue-templates): fix typo in label
2024-02-28 11:15:11 -08:00
Anonymoussaurus
930849c163
chore(issue-templates): fix typo in label 2024-02-28 20:12:43 +01:00
jxdv
42106ac4fc
Merge branch 'main' into ci-checksum 2024-02-28 15:07:39 +00:00
Anonymoussaurus
dfe7e52cd0
Merge pull request #282 from Universal-Debloater-Alliance/281-featissue-templates-use-issue-forms
chore(issue-templates): use issue forms
2024-02-28 12:58:42 +01:00
jxdv
22ed7415aa
Merge branch 'main' into ci-checksum 2024-02-27 20:21:14 +00:00
Anonymoussaurus
a5a3d9cae6
Merge pull request #302 from jxdv/update-list
fix: update desc / typos of uad_list
2024-02-27 12:18:29 +01:00
jxdv
3d6d84a617 more typos 2024-02-27 12:10:05 +01:00
jxdv
f2ca79cd37 fix typo in com.ape.gamemode 2024-02-27 12:04:19 +01:00
jxdv
527a907689 update com.sonymobile.pip 2024-02-27 12:02:25 +01:00
jxdv
d7cd243706
Merge branch 'main' into ci-checksum 2024-02-26 17:32:52 +00:00
Anonymoussaurus
e51513de5f
Merge pull request #301 from jxdv/fix-lists
fix: update uad list typos
2024-02-26 18:12:17 +01:00
jxdv
0923e214c6
Merge branch 'main' into fix-lists 2024-02-26 16:48:30 +00:00
jxdv
8ebf77b401 fix more typos 2024-02-26 17:45:40 +01:00
jxdv
64dff49d11 lyrics typo 2024-02-26 17:42:03 +01:00
jxdv
fa8994aef1
Merge branch 'main' into ci-checksum 2024-02-26 15:35:36 +00:00
jxdv
7c3d09a5e3 update release.yml 2024-02-26 16:34:42 +01:00
jxdv
31bc67e220 fix windows checksum format 2024-02-26 16:15:41 +01:00
Anonymoussaurus
5c03245dc2
pkg(com.sec.android.app.launcher): improve description 2024-02-25 22:41:59 +01:00
Anonymoussaurus
acd905c6ec
Merge pull request #294 from Universal-Debloater-Alliance/231-one-ui-packages
pkg(samsung): add Samsung packages
2024-02-25 19:41:10 +01:00
Anonymoussaurus
52114fe575
Merge pull request #293 from Universal-Debloater-Alliance/212-comgoogleandroidappsmessaging-should-be-advanced
pkg(com.google.android.apps.messaging): change description
2024-02-25 19:22:56 +01:00
Anonymoussaurus
ad17c3dd5d
Merge pull request #292 from Universal-Debloater-Alliance/195-comhuaweimultimediaaudioengine-wrong-description
pkg(com.huawei.multimedia.audioengine): change description
2024-02-25 19:22:44 +01:00
Anonymoussaurus
3272d35f98
Merge pull request #290 from Universal-Debloater-Alliance/85-rest-of-huawei-missing-packages
pkg(huawei-apps): add package and change descriptions
2024-02-25 19:22:32 +01:00
jxdv
7c75cd50fd fix upload ci 2024-02-25 18:21:23 +01:00
jxdv
019e4c417f remove bin/ 2024-02-25 18:15:55 +01:00
Anonymoussaurus
0efa49af8c
pkg(samsung): add Samsung packages 2024-02-25 16:59:24 +01:00
Anonymoussaurus
ac672d96ce
pkg(samsung): add Samsung packages 2024-02-25 16:47:28 +01:00
Anonymoussaurus
a97d645db4
pkg(com.google.android.apps.messaging): change description 2024-02-25 16:36:38 +01:00
Anonymoussaurus
8e6afa382f pkg(com.huawei.multimedia.audioengine): change description 2024-02-25 16:17:55 +01:00
Anonymoussaurus
029acf66d3
pkg(huawei-apps): add package and change descriptions 2024-02-25 15:12:19 +01:00
Anonymoussaurus
fd20e7d23d chore(issue-templates): add issue forms 2024-02-25 01:34:02 +01:00
Anonymoussaurus
e09542a9a4 chore(issue-templates): add issue form for feature requests 2024-02-25 01:34:02 +01:00
Anonymoussaurus
109f3ffbc9 chore(issue-templates): include link in textarea 2024-02-25 01:34:02 +01:00
Anonymoussaurus
421384004c chore(issue-templates): use issue forms 2024-02-25 01:34:02 +01:00
Anonymoussaurus
778d7f7f52
Merge pull request #289 from Universal-Debloater-Alliance/fix/update-manifest-links
Update UADng links in Cargo.toml
2024-02-24 22:14:03 +01:00
Frigyes
151c343069
Update UADng links in Cargo.toml 2024-02-24 12:53:50 -08:00
Adhiraj S. Chauhan
bac98ac067
Merge pull request #288 from Universal-Debloater-Alliance/1.0.2-release-preparation
1.0.2 Release preparation
2024-02-24 22:29:00 +05:30
Adhiraj S. Chauhan
dedd8c0455
Merge pull request #287 from Universal-Debloater-Alliance/fix/ci-script-mistakes
fix(ci): sha256sum errors and overwrites
2024-02-24 22:28:30 +05:30
Frigyes06
6c512c7964
Bumped UAD-ng version and updated lockfile 2024-02-24 08:45:44 -08:00
Frigyes06
d87f5b3236
fix(ci): sha256sum errors and overwrites 2024-02-24 08:32:36 -08:00
Himadri Bhattacharjee
a07345eb8d
Merge pull request #286 from Universal-Debloater-Alliance/1.0.1-release-preparation
1.0.1 release preparation
2024-02-24 18:53:39 +05:30
“Frigyes06”
b328916152
cargo updated cargo.lock 2024-02-23 13:35:28 -08:00
Adhiraj S. Chauhan
feafb7f1e4
Merge pull request #203 from Universal-Debloater-Alliance/list-to-map
refactor(program): make UAD-ng list have key value pair for directly building hashmap
2024-02-24 01:33:51 +05:30
Himadri Bhattacharjee
17a6656f07
feat: make uad-ng have key value pair for directly building hashmap
chore: update list to reflect new packages

tests: fix tests for parsing json file

lint: cargo clippy
2024-02-24 01:23:42 +05:30
“Frigyes06”
157bfbc51f
Bump UADng version in cargo.toml 2024-02-23 11:18:51 -08:00
Frigyes
7736508998
Merge pull request #279 from Universal-Debloater-Alliance/add-documentation-template
chore(issue-templates): add documentation template
2024-02-21 12:06:43 -08:00
Anonymoussaurus
2d48daafe0
chore(issue-templates): add documentation template 2024-02-21 21:03:13 +01:00
Anonymoussaurus
c6c75523a2
Merge pull request #278 from xe1st/patch-1
webview package description update
2024-02-21 20:01:21 +01:00
xe1st
de4b079cf3 Update uad_lists.json
webview package description update

Update uad_lists.json
2024-02-21 21:24:00 +03:00
Adhiraj S. Chauhan
b826a54777
Merge pull request #275 from Universal-Debloater-Alliance/feat/release-pipeline-fixes
feat(ci): changed release notes to use github's auto generated one
2024-02-21 13:18:03 +05:30
“Frigyes06”
64d0299619
reverted some changes 2024-02-20 13:50:15 -08:00
Frigyes06
136e490732
Changed release notes to use github's auto generated one. 2024-02-19 14:21:49 -08:00
Anonymoussaurus
c56a6f6f87
Merge pull request #257 from qumuq-til/patch-1
Update uad_lists.json, Duraspeed info
2024-02-19 11:01:47 +01:00
qumuq-til
8d9a5834b5 Update uad_lists.json, Duraspeed info
Duraspeed mentioned here is just an UI component. As such, uninstalling it may lead to unintended consequences.
2024-02-19 11:01:31 +01:00
Anonymoussaurus
0796c7d1b1
Merge pull request #273 from Universal-Debloater-Alliance/272-buguad-ng-list
pkg: add MiBox, OPPO and Pixel packages
2024-02-19 10:05:52 +01:00
blitziak
17b854d919
mibox, oppo, pixel PRs 2024-02-18 23:13:22 +00:00
blitziak
de83d90e26
removed mibox lists and corrected moto after them 2024-02-18 20:30:13 +00:00
Anonymoussaurus
ea05f48514
Merge pull request #245 from Universal-Debloater-Alliance/Blitz517-patch-1
XIAOMI MIBOX 4 APKS
2024-02-18 17:21:58 +01:00
blitziak
05fae9e681
XIAOMI MIBOX 4 APKS 2024-02-18 17:09:06 +01:00
Anonymoussaurus
1c71ddb4db
Merge pull request #268 from Universal-Debloater-Alliance/246-pkg-improve-descriptions-for-aosp-and-transsion
pkg: improve descriptions and removals for AOSP and Transsion
2024-02-18 17:04:31 +01:00
Adhiraj S. Chauhan
06597064d3
Merge pull request #229 from Universal-Debloater-Alliance/improve-issue-templates
chore(issue-templates): improve default title text
2024-02-18 18:13:50 +05:30
Anonymoussaurus
87fd2f5338
chore(issue-templates): add scope to title placeholder 2024-02-18 13:43:01 +01:00
Anonymoussaurus
3caf767e6c
Merge pull request #271 from Artem13327/patch-2
com.google.android.apps.wellbeing now advanced
2024-02-18 13:35:30 +01:00
Anonymous
b43a4615d2
com.google.android.apps.wellbeing now advanced 2024-02-18 14:24:40 +03:00
Himadri Bhattacharjee
4e90e1b17c
Merge pull request #269 from Universal-Debloater-Alliance/feature/update-use-github-latest
feat(update): switch to using GitHub's latest release API
2024-02-18 07:29:42 +05:30
Adhiraj Singh Chauhan
b78e630c83
feat(update): fetch only latest release info
The original (abandoned) project only had pre-releases, but we've moved on from that ever since releasing v1.0.0.
So instead of fetching all releases only to pick the topmost one, we can now simply use GitHub's latest release API to be less wasteful.
2024-02-17 21:21:51 +05:30
Anonymoussaurus
c62ad0eb36
pkg: improve descriptions and removals for AOSP and Transsion 2024-02-17 16:23:29 +01:00
Anonymoussaurus
9b9a81e10c
Merge pull request #264 from Artem13327/patch-1
com.google.android.deskclock now Advanced
2024-02-17 13:24:09 +01:00
Anonymous
363df04e47
com.google.android.deskclock now Advanced 2024-02-16 23:19:03 +03:00
Adhiraj S. Chauhan
9961bdc7a2
Merge pull request #261 from Universal-Debloater-Alliance/fix/user-flag
fix: pass user flag when sdk version is 21 or above
2024-02-15 17:20:10 +05:30
Himadri Bhattacharjee
37a96980ce fix: pass user flag when sdk version is 21 or above
fixes regression introduced in 6ffba9d40e
2024-02-15 08:46:19 +05:30
blitziak
8f8f556167
Motorola more apps and better descriptions. (#252)
* Motorola more apps and better descriptions.

* solved problems

Suggestion commit doesn't work, but I did everything needed.

* pkg(com.motorola.android.fota): change removal to `Expert`

---------

Co-authored-by: Anonymoussaurus <50231698+AnonymousWP@users.noreply.github.com>
2024-02-14 18:34:11 +01:00
Adhiraj S. Chauhan
7d4e25b2a2
Merge pull request #259 from Universal-Debloater-Alliance/feat/prepend-v
feat(ui): prepend v in front of version in navigation menu
2024-02-14 07:37:09 +05:30
“Frigyes06”
c6de23daed
Prepend v in front of version in navigation menu 2024-02-13 13:13:12 -08:00
Anonymoussaurus
1c99d73b7c
Merge pull request #247 from xe1st/patch-1
Change package descriptions and categories
2024-02-12 15:11:48 +01:00
xe1st
10f12f45dd
Update uad_lists.json 2024-02-12 15:42:29 +03:00
Anonymoussaurus
8ca6e69574
Merge pull request #232 from Universal-Debloater-Alliance/175-new-packagess
pkg(samsung): add two packages
2024-02-12 11:01:16 +01:00
Anonymoussaurus
5a63869714
Merge pull request #208 from Universal-Debloater-Alliance/200-suggestion-on-packages
pkg(com.android.soundrecorder): improve description
2024-02-12 10:51:01 +01:00
Anonymoussaurus
4780577a6c
Merge pull request #241 from Universal-Debloater-Alliance/240-svcagent
pkg(samsung): update descriptions of `com.samsung.android.smartface` and `com.samsung.android.svcagent`
2024-02-12 10:45:13 +01:00
Anonymoussaurus
70247ef369 pkg(com.samsung.android.svcagent): change description 2024-02-12 10:44:53 +01:00
Anonymoussaurus
9b521cf513 pkg(com.samsung.android.smartface): fix JSON-error 2024-02-12 10:44:53 +01:00
Himadri Bhattacharjee
c06bde1d68
Merge pull request #243 from Universal-Debloater-Alliance/clippy-lints
lint: apply clippy suggestions
2024-02-12 15:03:05 +05:30
Himadri Bhattacharjee
37c09f9ac6 deps: update cargo.lock 2024-02-12 14:18:49 +05:30
Himadri Bhattacharjee
4ced64412e lint: apply clippy suggestions 2024-02-12 14:08:31 +05:30
Himadri Bhattacharjee
2cccec28c2
Merge pull request #238 from B0ney/fix/show-logs-on-windows
fix: allow the app to display logs when launced from the terminal on windows
2024-02-12 13:47:52 +05:30
Adhiraj S. Chauhan
e7401a1f17
Merge pull request #236 from Universal-Debloater-Alliance/strip-version-prefix
fix: strip `v` version prefix when checking for updates
2024-02-12 13:10:53 +05:30
Frigyes
33ba195f48
remove extra spaces 2024-02-11 21:01:02 -08:00
Anonymoussaurus
b7850f8d85 pkg(aosp): change description and removal 2024-02-11 23:31:59 +01:00
Anonymoussaurus
5428e17372 pkg(com.android.soundrecorder): improve description 2024-02-11 23:31:59 +01:00
Anonymoussaurus
aba6af3486 pkg(com.samsung.android.photoremasterservice): add package 2024-02-11 23:18:08 +01:00
Anonymoussaurus
0b9eabc33d pkg(samsung): add com.samsung.android.wallpaper.res 2024-02-11 23:18:08 +01:00
Prakhar Baranwal
3526951917
update some samsung pkgs (#192)
* update some samsung pkgs

* small fixes

* small fix

* phone -> your phone
2024-02-11 12:55:55 +01:00
Himadri Bhattacharjee
238a563f2b lint: cargo fmt and clippy 2024-02-11 11:06:12 +05:30
B0ney
4ce499553d use win32console instead of windows_sys for a safer abstraction. 2024-02-10 15:54:22 +00:00
B0ney
414f9918bd fix: allow the app to display logs when launced from the terminal on windows. 2024-02-10 15:05:52 +00:00
Himadri Bhattacharjee
684ee331ef lint: cargo clippy 2024-02-10 18:33:24 +05:30
Himadri Bhattacharjee
0f64f23dc7 fix: strip v version prefix when checking for updates 2024-02-10 18:29:51 +05:30
Himadri Bhattacharjee
d93e3b498e
Merge pull request #234 from Universal-Debloater-Alliance/169-new-packages
pkg(samsung): add package and changed description/removal
2024-02-10 12:50:30 +00:00
blitziak
84e87f71c2
Merge pull request #235 from Universal-Debloater-Alliance/211-removing-comheytappictorial-partially-or-completely-breaks-the-lock-screen-wallpaper-on-my-realme-device
pkg(com.heytap.pictorial): change removal and description
2024-02-09 23:43:26 +01:00
Anonymoussaurus
72b64f096f
pkg(com.heytap.pictorial): change removal and description 2024-02-09 12:29:21 +01:00
Anonymoussaurus
ed33e613eb
pkg(samsung): add package and changed description/removal 2024-02-09 12:14:07 +01:00
Himadri Bhattacharjee
ccfc3ef3b5
Merge pull request #233 from Universal-Debloater-Alliance/fix/ci-script-fixes
fix(ci): Remove renderer matrix completely
2024-02-09 04:29:30 +00:00
Frigyes06
9977cb6c33
removed matrix from workflow names 2024-02-08 19:19:47 -08:00
“Frigyes06”
6a6f92ffae
Remove renderer matrix completely 2024-02-08 14:44:35 -08:00
Adhiraj S. Chauhan
c4b84b8bdb
Merge pull request #230 from edgy-b/UI-improvements
feat(ui): don't force users to update without showing 'Apps' tab
2024-02-09 03:12:57 +05:30
Ed B
838034927b - fix cargo fmt checks 2024-02-08 23:14:12 +02:00
Ed B
9f742390a1 - don't force user update without showing Apps tab 2024-02-08 19:03:21 +02:00
Anonymoussaurus
75b2d098fe
Merge pull request #191 from Universal-Debloater-Alliance/Blitz517-patch-1
Google Chromecast APKs
2024-02-08 12:21:54 +01:00
blitziak
c6f9bffb1d fixed + improved descriptions
google play + comments approved + my thoughts again for some apps (because some of these apps look different on other Android TVs)
2024-02-08 12:18:42 +01:00
blitziak
17cd6b9573 Google Chromecast APKs
from android tv
2024-02-08 12:18:42 +01:00
Anonymoussaurus
1a18b4a277
chore(issue-templates): improve default title text 2024-02-08 00:07:15 +01:00
Frigyes
3bd139302e
Merge pull request #226 from Universal-Debloater-Alliance/222-buguad-ng-about-redundant-v-is-prepended-when-checking-for-version
fix(program): redundant prepended 'v'
2024-02-07 12:01:36 -08:00
Anonymoussaurus
9f8b45728e
fix(uad-ng — about): redundant prepended 'v' 2024-02-07 19:58:08 +01:00
Anonymoussaurus
a2ae18e5a1
Merge pull request #219 from eleius/patch-1
Update build_artifacts.yml
2024-02-07 10:19:12 +01:00
eleius
18be429f50
Update build_artifacts.yml
typo
2024-02-07 08:59:01 +00:00
Anonymoussaurus
84ba6e77ab
Merge pull request #216 from Universal-Debloater-Alliance/feature/improve-changelog-labeling
feat(docs): Changelog generation improvement
2024-02-06 23:53:49 +01:00
Frigyes
be56c87cb2
feat(docs): Changelog generation improvement 2024-02-06 14:41:57 -08:00
Adhiraj S. Chauhan
8784764ac5
Merge pull request #197 from Universal-Debloater-Alliance/Frigyes06-patch-1
feat: add logo to taskbar and window
2024-02-07 02:02:44 +05:30
Anonymoussaurus
02e8ebb022
Merge pull request #214 from Universal-Debloater-Alliance/fix-update-ci-dependencies
build(ci): update actions dependencies to newer versions
2024-02-06 20:37:11 +01:00
“Frigyes06”
1085ec96d1 Update actions dependencies to newer versions 2024-02-06 20:36:52 +01:00
Adhiraj Singh Chauhan
a6df57f186 feat: add icon to window settings 2024-02-06 11:36:36 -08:00
“Frigyes06”
9eb03288da Transparent deez 2024-02-06 11:36:36 -08:00
Frigyes
c13e1a22e9 Add logo.png to resources 2024-02-06 11:36:36 -08:00
Adhiraj S. Chauhan
5882a70047
Merge pull request #213 from Universal-Debloater-Alliance/fix-remove-glow-from-ci
fix: Remove glow target from CI script
2024-02-07 00:54:16 +05:30
“Frigyes06”
5a61187c4b
Removed glow from CI 2024-02-06 11:16:08 -08:00
Anonymoussaurus
dbd2619425
Merge pull request #207 from Universal-Debloater-Alliance/199-add-new-package-cnwpsxiaomiabroadlite-mi-doc-viewer
pkg(cn.wps.xiaomi.abroad.lite): improve description
2024-02-05 23:47:00 +01:00
Anonymoussaurus
d71a07696f
Merge pull request #209 from Universal-Debloater-Alliance/206-please-move-nothingcardservice-out-of-recommendation-list
pkg(om.nothing.cardservice): change `removal` and improve description
2024-02-05 23:46:19 +01:00
Anonymoussaurus
56e0eb51a8
Merge pull request #210 from Universal-Debloater-Alliance/readme-to-wiki
feat: move most of the documentation to the wiki
2024-02-05 11:51:19 +01:00
Anonymoussaurus
5d0f0ce02c
docs(readme): add link to wiki 2024-02-05 11:51:00 +01:00
Himadri Bhattacharjee
8eb8aa1f04
Merge branch 'main' into readme-to-wiki 2024-02-05 04:03:27 +00:00
Himadri Bhattacharjee
fde97a1c57 feat: move most of the documentation to the wiki 2024-02-05 09:30:31 +05:30
Anonymoussaurus
d416bae8e7
pkg(om.nothing.cardservice): change removal and improve description 2024-02-04 23:12:43 +01:00
Anonymoussaurus
3361d80cd5
pkg(cn.wps.xiaomi.abroad.lite): improve description 2024-02-04 23:06:56 +01:00
Frigyes
138379bd31
Merge pull request #186 from Universal-Debloater-Alliance/183-include-this-in-the-readme-and-maybe-in-the-app-itself-as-a-warning
docs(readme): add FAQ item
2024-02-02 20:47:56 -08:00
Adhiraj S. Chauhan
eac72936df
Merge pull request #196 from Universal-Debloater-Alliance/summary-struct
feat: create summary struct to describe summary entries
2024-02-01 16:10:53 +05:30
Adhiraj S. Chauhan
aaf5d0a566
Merge pull request #198 from Universal-Debloater-Alliance/adb-missing-exit
fix: exit when adb is not found
2024-02-01 16:05:22 +05:30
Himadri Bhattacharjee
670870577c fix: exit when adb is not found 2024-02-01 09:04:12 +05:30
Anonymoussaurus
9760200a06
Merge pull request #133 from Universal-Debloater-Alliance/122-Change-default-thame-to-Dark
feat(ui): change default theme to Dark
2024-01-29 09:49:31 +01:00
Himadri Bhattacharjee
9aee3a6bfa
Merge pull request #119 from B0ney/remove-glow
feat: remove glow feature
2024-01-28 11:05:27 +00:00
Himadri Bhattacharjee
db7bea9fd2 feat: use cheaper 5 element slice for summary entries 2024-01-27 17:13:34 +05:30
Anonymoussaurus
d209cc8278
Merge pull request #189 from jxdv/edit-list
fix uad_lists.json
2024-01-26 17:07:43 +01:00
jxdv
684555f79b fix uad_lists.json 2024-01-26 17:03:59 +01:00
Anonymoussaurus
b9bc352372
Merge pull request #187 from prakharb5/patch-1
pkg: Add samsung shop
2024-01-26 16:37:43 +01:00
Prakhar Baranwal
ac5ded0193
pkg: Add samsung shop 2024-01-26 21:06:12 +05:30
Frigyes
9cc176efc5
pkg(simple-apps): remove all recommendations of Simple apps (#161)
* Removed all recommendations of Simple apps. Fixes #158

* fix(typo): "have" -> "has" for "OpenBoard is FOSS…" text

* Removed all recommendations of Simple apps. Fixes #158

* fix(typo): "have" -> "has" for "OpenBoard is FOSS…" text

* pkg(keyboards): revert removal of Simple Keyboard

* pkg(keyboards): remove keyboard recommendation

---------

Co-authored-by: Adhiraj Singh Chauhan <adhirajsinghchauhan@gmail.com>
Co-authored-by: Anonymoussaurus <50231698+AnonymousWP@users.noreply.github.com>
2024-01-26 15:57:14 +01:00
Anonymoussaurus
7abaea151b
docs(readme): add FAQ item 2024-01-26 15:39:00 +01:00
Adhiraj S. Chauhan
622ea98ce7
Merge pull request #172 from lavafroth/backup-struct-aot
refactor: create a backup struct ahead of time
2024-01-19 20:55:02 +05:30
Himadri Bhattacharjee
a4aab2ecf3
Merge branch 'Universal-Debloater-Alliance:main' into backup-struct-aot 2024-01-13 17:11:37 +05:30
Adhiraj S. Chauhan
60602bb9b9
Merge pull request #153 from Universal-Debloater-Alliance/fix/release-workflow-runs-unnecessarily
fix(workflow): release.yml workflow's build job runs when it shouldn't
2024-01-12 18:02:57 +05:30
Himadri Bhattacharjee
da37301253
Merge branch 'Universal-Debloater-Alliance:main' into backup-struct-aot 2024-01-12 17:55:47 +05:30
Adhiraj S. Chauhan
b2426ce450
Merge pull request #162 from lavafroth/unwrap-or-default
refactor: use default values with `unwrap_or_default`
2024-01-10 14:04:44 +05:30
Adhiraj S. Chauhan
216761e520
Merge pull request #165 from lavafroth/unused-variant-string
refactor: remove unused string inside enum variants
2024-01-10 12:24:11 +05:30
Frigyes
399461f972
Merge pull request #170 from Universal-Debloater-Alliance/docs/remove-singular-language
docs(readme): remove singular language
2024-01-09 15:37:20 -08:00
Anonymoussaurus
8b38b91873
docs(readme): remove singular language 2024-01-09 23:38:36 +01:00
Himadri Bhattacharjee
3d14f5f951 fix: revert waiting_view argument to false 2024-01-09 09:48:18 +01:00
Himadri Bhattacharjee
38aaecbef8 feat: use derive attribute for default variant 2024-01-09 09:48:18 +01:00
Himadri Bhattacharjee
e4abc917a2 refactor: remove string from enum variants where it is unused
refactor: remove string from enum variants where it is unused
2024-01-09 09:48:18 +01:00
blitziak
1caa1f08ca
Merge pull request #167 from Universal-Debloater-Alliance/166-app-vault-package-commiandroidglobalminusscreen
pkg(`com.mi.android.globalminusscreen`): update description
2024-01-08 23:16:42 +01:00
Anonymoussaurus
7f7917b416
pkg(com.mi.android.globalminusscreen): update description 2024-01-08 22:59:43 +01:00
Himadri Bhattacharjee
cc1cd817c6 feat: build backup struct ahead of time 2024-01-08 16:37:20 +05:30
Adhiraj Singh Chauhan
b9260dd5b6
feat(workflow): run release.yml only if a semver tag is pushed on main 2024-01-08 11:02:17 +05:30
Adhiraj Singh Chauhan
a444a8c1c5
fix(workflow): release's build job runs when it shouldn't
This should've been part of #152, but oh well.
2024-01-08 11:02:17 +05:30
Frigyes
e18231ee59
Merge pull request #163 from Universal-Debloater-Alliance/feat/generate-checksums-for-release-files
feat: add checksum making commands
2024-01-07 21:08:45 -08:00
Himadri Bhattacharjee
59f0337380 fix: move run line to appropriate blocks 2024-01-08 04:52:36 +00:00
Himadri Bhattacharjee
7ef7e0eaae fix: separate creating checksums for platforms 2024-01-08 04:51:17 +00:00
Himadri Bhattacharjee
0ef99c1f75 fix: don't try renaming archive with shorthand especially on windows 2024-01-08 04:09:55 +00:00
B0ney
48b5365ba5
Merge branch 'Universal-Debloater-Alliance:main' into remove-glow 2024-01-07 11:04:07 +00:00
“Frigyes06”
a95844f033
Added checksum making commands 2024-01-06 21:59:21 -08:00
Himadri Bhattacharjee
51a671783e
Merge branch 'Universal-Debloater-Alliance:main' into unwrap-or-default 2024-01-07 05:26:30 +00:00
Frigyes
d888536966
Merge pull request #156 from lavafroth/refactor
refactor: use if-let binding for getting package attributes
2024-01-06 21:15:31 -08:00
Frigyes
5114fdef48
Merge pull request #160 from lavafroth/bool-then-some
refactor: select optional user struct based on SDK version conditional
2024-01-06 20:51:56 -08:00
Frigyes
574705209f
Merge pull request #159 from nain-F49FF806/patch-1
Update description of `com.samsung.android.app.omcagent`
2024-01-06 20:51:00 -08:00
Himadri Bhattacharjee
14139dcbca
Merge branch 'main' into refactor 2024-01-06 12:52:18 +00:00
Himadri Bhattacharjee
3e0fef4b8e
Merge branch 'Universal-Debloater-Alliance:main' into bool-then-some 2024-01-06 12:46:33 +00:00
Himadri Bhattacharjee
618014bd26 refactor: use default for optional values instead of being explicit 2024-01-06 14:40:45 +05:30
Himadri Bhattacharjee
6ffba9d40e refactor: select optional user based on sdk, then build request
use the boolean .then_some method to create an `Option`al user based on the Android SDK, then build a request
2024-01-06 14:35:02 +05:30
nain-F49FF806
a1387edb42
Update description of omcagent
Remove confusing information, and add better description.
2024-01-06 09:46:19 +01:00
Anonymoussaurus
01b9f244ca
Merge pull request #155 from lavafroth/fix-descriptions
fix: grammar and repetitive descriptions
2024-01-05 19:47:19 +01:00
Himadri Bhattacharjee
5735aa57b0
Merge branch 'main' into refactor 2024-01-05 04:56:14 +00:00
Himadri Bhattacharjee
8f66647ad2 refactor: use if-let binding for getting package attributes 2024-01-05 10:23:36 +05:30
Himadri Bhattacharjee
69f35faa7e fix: apply suggested changes 2024-01-05 03:51:51 +00:00
Himadri Bhattacharjee
53d8520998 fix: grammar and repetitive descriptions 2024-01-05 03:51:51 +00:00
Frigyes
5058d8bcb3
Merge pull request #154 from Universal-Debloater-Alliance/docs/remove-gui-part
docs: remove explicit mention of 'GUI'
2024-01-04 09:00:19 -08:00
Anonymoussaurus
db1a1a5fc8
docs: remove explicit mention of 'GUI'
It's unnecessary as everyone is already familiar with the name. Barely anyone uses the CLI-version now.
2024-01-04 11:30:58 +01:00
Adhiraj S. Chauhan
9785944558
Merge pull request #152 from Universal-Debloater-Alliance/fix/broken-things-after-name-change
Fix broken CI & code stuff after project name change
2024-01-04 08:27:38 +05:30
Adhiraj Singh Chauhan
410e6a0720
fix: incorrect log level configuration for our own crate 2024-01-04 07:40:22 +05:30
Adhiraj Singh Chauhan
a283202c9c
fix: cache/log directory was mistakenly changed from uad -> uad-ng 2024-01-04 07:39:12 +05:30
Adhiraj Singh Chauhan
1d985bd254
fix: auto-update, build_artifacts & release workflows were broken 2024-01-04 07:37:08 +05:30
B0ney
167b9b746e
Merge branch 'Universal-Debloater-Alliance:main' into remove-glow 2024-01-03 18:07:36 +00:00
B0ney
637912e408 Merge branch 'remove-glow' of https://github.com/B0ney/universal-android-debloater into remove-glow 2024-01-03 17:59:16 +00:00
Anonymoussaurus
8322123cf1
Merge pull request #131 from Universal-Debloater-Alliance/126-Discord-server-in-readme
docs(readme): add Discord invite
2024-01-03 10:43:15 +01:00
Frigyes
0bf83d08f9
Merge pull request #124 from Universal-Debloater-Alliance/feat/rename-project-name-to-UAD-NG
feat: rename project name to Universal Android Debloater Next Generation (UAD-ng)
2024-01-02 19:52:10 -08:00
Frigyes
6434e51941
Merge branch 'main' into feat/rename-project-name-to-UAD-NG 2024-01-02 19:51:33 -08:00
Frigyes
7e4da6b9b4
Merge pull request #150 from lavafroth/refresh-tooltip
feat(ui): remove useless divider and add a tooltip for the refresh button
2024-01-02 19:46:03 -08:00
Himadri Bhattacharjee
2bcc026f31
Merge branch 'main' into refresh-tooltip 2024-01-03 02:49:12 +00:00
Himadri Bhattacharjee
654628e93b feat: add tooltip to the refresh button 2024-01-03 08:18:18 +05:30
Frigyes
bffef62a5c
Merge pull request #149 from lavafroth/tooltip-styling
feat: add the default styling and gap to tooltip
2024-01-02 08:50:46 -08:00
Himadri Bhattacharjee
f6bb364a63 feat: add the default styling and gap to tooltip 2024-01-02 14:35:04 +05:30
Adhiraj S. Chauhan
540402852c
Merge pull request #146 from lavafroth/select-all-checkbox
feat(ui): move select and deselect all actions to more intuitive checkbox
2024-01-02 09:43:27 +05:30
Adhiraj Singh Chauhan
16d03a0e90
feat: use tooltip for select all checkbox instead of label 2024-01-02 09:32:57 +05:30
Himadri Bhattacharjee
bb292f4f4b Merge remote-tracking branch 'refs/remotes/origin/select-all-checkbox' 2024-01-02 08:21:22 +05:30
Himadri Bhattacharjee
b199086be5 fix: align select all button with other buttons 2024-01-02 08:21:08 +05:30
Himadri Bhattacharjee
06897b2bc7 fix: add "select all" label for accessibility 2024-01-02 08:20:48 +05:30
“Frigyes06”
461eaa61a1 Changed default theme 2024-01-01 21:38:00 +01:00
Frigyes
d6d0b94a69 Update README.md 2024-01-01 21:37:04 +01:00
“Frigyes06”
dfec55cb07 Updated text 2024-01-01 21:37:04 +01:00
“Frigyes06”
e585a70fe8 Aded discord invite to readme 2024-01-01 21:37:04 +01:00
AnonymousWP
c28e767644 fix: New Generation -> Next Generation 2024-01-01 21:35:04 +01:00
AnonymousWP
17b18c4ca7 feat: rename project name to Universal Android Debloater New Generation (UAD-ng) 2024-01-01 21:35:04 +01:00
B0ney
5e5779ac70 remove iced_glow from cargo.toml 2024-01-01 21:34:45 +01:00
Anonymoussaurus
c765e8edc9
Merge pull request #143 from lavafroth/fix-typos
doc: fix typos and bad grammar
2024-01-01 20:16:13 +01:00
Himadri Bhattacharjee
278de6bd8a
Merge branch 'main' into select-all-checkbox 2024-01-01 12:50:45 +00:00
Himadri Bhattacharjee
6a1fee9acc feat: move select and deselect all actions to more intuitive checkbox 2024-01-01 18:17:31 +05:30
Himadri Bhattacharjee
56d328de75
Merge branch 'main' into fix-typos 2024-01-01 06:46:08 +00:00
blitziak
6f8e388a19
Merge pull request #141 from nixingyang/com.miui.miinput
[CHG] Move the "com.miui.miinput" package to the "Advanced" category.
2023-12-31 22:04:02 +01:00
Himadri Bhattacharjee
dae8a29fe5 doc: fix typos and bad grammar 2023-12-31 21:13:56 +05:30
nixingyang
f3e9d6c0e6 [CHG] Move the "com.miui.miinput" package to the "Advanced" category. 2023-12-31 16:17:43 +02:00
blitziak
ed71ae00b8
Merge pull request #139 from Universal-Debloater-Alliance/125-removing-optimiser-comhuaweisystemmanager-disables-the-functionality-of-closing-and-cleaning-background-apps
pkg(`com.huawei.systemmanager`): add note to description
2023-12-28 23:58:01 +01:00
AnonymousWP
b8d1c04b79 pkg(com.huawei.systemmanager): add note to description 2023-12-28 23:52:00 +01:00
blitziak
8d6558aa0c
Merge pull request #140 from Universal-Debloater-Alliance/138-infinix-specific-heavy-bloat
pkg(`com.transsion.magazineservice.xos`): add package
2023-12-28 22:20:43 +01:00
AnonymousWP
5e5718ce8c
pkg(com.transsion.magazineservice.xos): add package 2023-12-28 21:49:30 +01:00
Anonymoussaurus
8829e65458
Merge pull request #137 from Universal-Debloater-Alliance/chore/replace-screenshot-in-readme
chore: replace screenshot in README
2023-12-28 21:46:48 +01:00
“Frigyes06”
88de115c54
Updated screenshot in README 2023-12-27 19:48:43 -08:00
blitziak
a35e5817c4
Merge pull request #111 from Universal-Debloater-Alliance/110-osulogin
pkg(`com.google.android.hotspot2.osulogin`): add package
2023-12-25 13:15:01 +01:00
AnonymousWP
b2a3de1d45 pkg(com.google.android.hotspot2.osulogin): add package 2023-12-25 01:18:06 +01:00
B0ney
77a7abf98d remove iced_glow from cargo.toml 2023-12-24 22:37:56 +00:00
Adhiraj S. Chauhan
e049bc6ec5
Merge pull request #118 from Universal-Debloater-Alliance/feature/standardized-font-size-and-layout-fixes
Feature/standardized font size and layout fixes
2023-12-25 03:47:40 +05:30
“Frigyes06”
8be24250eb
fixed icon width 2023-12-24 14:12:39 -08:00
“Frigyes06”
c5ea5aa2dd
changed default font size, removed unnecessary sizes 2023-12-24 14:09:14 -08:00
Adhiraj S. Chauhan
7048ecaf4a
Merge pull request #117 from Universal-Debloater-Alliance/feature/scrollable-settings
feat(settings): made it scrollable
2023-12-25 03:34:23 +05:30
“Frigyes06”
1e77f48685
fixed layout once more 2023-12-24 13:56:34 -08:00
“Frigyes06”
88eaee3cc1
fixed search bar 2023-12-24 13:56:34 -08:00
“Frigyes06”
787c7d1f63
Standardized font sizes and fixed selection review popup 2023-12-24 13:56:24 -08:00
Adhiraj Singh Chauhan
2acb494849
feat(settings): made it scrollable 2023-12-25 02:36:42 +05:30
Frigyes
3f18b8249f
Merge pull request #107 from Universal-Debloater-Alliance/dev
chore: clean up dev to merge into main and then delete
2023-12-24 13:02:11 -08:00
“Frigyes06”
09ad83bedc
updated lockfile 2023-12-25 02:26:20 +05:30
B0ney
388fdef53a
Update modal widget to run on iced 0.10.0, remove iced_native 2023-12-25 02:26:20 +05:30
“Frigyes06”
fef6ab8c28
Updated widget in modal.rs 2023-12-25 02:26:19 +05:30
Adhiraj Singh Chauhan
5fb4c2c3b8
fix: errors E0223 and E0308 introduced by updating iced 0.9.0 -> 0.10.0 2023-12-25 02:26:19 +05:30
“Frigyes06”
6f31025110
bumped iced and glow 2023-12-25 02:26:17 +05:30
Anonymoussaurus
02dbd757ab
Merge pull request #108 from Universal-Debloater-Alliance/docs/contributing
docs(contributing): add `CONTRIBUTING.md`
2023-12-21 15:45:59 +01:00
AnonymousWP
9e1e776230 docs(contributing): add CONTRIBUTING.md 2023-12-21 15:11:51 +01:00
blitziak
bfab91f0c7
Merge pull request #104 from Universal-Debloater-Alliance/99-samsung-apexservice
pkg(`com.sec.android.app.apex`): change removal and improve description
2023-12-20 16:08:59 +01:00
blitziak
6248c892eb
Merge pull request #103 from Universal-Debloater-Alliance/98-ocrdataprovider
pkg(`com.samsung.android.sdk.ocr`): change removal and improve description
2023-12-20 16:08:31 +01:00
blitziak
e08c876cd8
Merge pull request #102 from Universal-Debloater-Alliance/91-one-ui-56-packages
pkg(samsung): add OneUI 5 and 6 packages
2023-12-20 16:07:49 +01:00
AnonymousWP
9daa469603 pkg(com.sec.android.app.apex): change removal and improve description 2023-12-20 00:21:31 +01:00
AnonymousWP
c76c00aa27 pkg(com.samsung.android.sdk.ocr): change removal and improve description 2023-12-20 00:21:01 +01:00
Anonymoussaurus
f234b506c3
Merge branch 'main' into 91-one-ui-56-packages 2023-12-20 00:19:07 +01:00
Frigyes
488fce1f70
Merge pull request #105 from Universal-Debloater-Alliance/95-add-removals-to-issue-template
chore(issue-template): explain removals
2023-12-19 15:16:34 -08:00
AnonymousWP
67485180a1
pkg(samsung): add OneUI 5 and 6 packages 2023-12-19 22:07:08 +01:00
AnonymousWP
26151a9c8e
chore(issue-template): explain removals 2023-12-19 22:01:46 +01:00
Frigyes
a12cf41195
Merge pull request #94 from Universal-Debloater-Alliance/Blitz517-patch-1
added one app and removal update for network, qualcomm app
2023-12-18 10:08:18 -08:00
blitziak
1bc9357822
Update uad_lists.json 2023-12-18 00:08:14 +00:00
blitziak
c850dd1199
added one app and removal update for network, qualcomm app 2023-12-17 21:52:44 +00:00
Anonymoussaurus
75ae571a01
Merge pull request #90 from prakharb5/patch-2
Update warning for samsung package
2023-12-17 11:12:53 +01:00
Prakhar Baranwal
db40ccbca0
Update warning for package 2023-12-17 12:36:31 +05:30
blitziak
27376ac499
Merge pull request #89 from Universal-Debloater-Alliance/79-packages-required-to-be-able-to-add-esim-to-samsung-devices
pkg(samsung): change description and removal
2023-12-17 00:49:54 +01:00
Anonymoussaurus
cbcf59ca69
Merge branch 'main' into 79-packages-required-to-be-able-to-add-esim-to-samsung-devices 2023-12-17 00:45:55 +01:00
Anonymoussaurus
0feeaccf7b
Merge pull request #88 from Universal-Debloater-Alliance/78-removing-samsung-contacts-app-breaks-medical-info-emergency-contacts-section-under-safety-and-emergency
pkg(`com.samsung.android.app.contacts`): add details to description
2023-12-17 00:45:27 +01:00
AnonymousWP
0c4ed54eb9
pkg(samsung): change description and removal 2023-12-17 00:35:15 +01:00
AnonymousWP
a4c0cdc148
pkg(com.samsung.android.app.contacts): add details to description 2023-12-17 00:13:28 +01:00
blitziak
3236d01793
Added/Updated packages a lot of packages/descriptions (#86)
* Added/Updated packages, descriptions

added more packages and used from old pull requests add/changes packages, descriptions.

* style: fix typos

* reviewed

---------

Co-authored-by: Anonymoussaurus <50231698+AnonymousWP@users.noreply.github.com>
2023-12-16 23:14:46 +01:00
Prakhar Baranwal
861b427703
Add some samsung apps (#84)
* Add some samsung apps

* fix removal priority for quick share agent

* fix wording
2023-12-16 13:56:51 +01:00
91 changed files with 36101 additions and 22160 deletions

View file

@ -1,6 +0,0 @@
[target.x86_64-pc-windows-msvc]
rustflags = ["-C", "target-feature=+crt-static"]
[target.x86_64-unknown-linux-gnu]
linker = "clang"
rustflags = ["-C", "link-arg=-fuse-ld=mold"]

2
.cargo/config.toml Normal file
View file

@ -0,0 +1,2 @@
[target.x86_64-pc-windows-msvc]
rustflags = ["-C", "target-feature=+crt-static"]

View file

@ -1,10 +0,0 @@
version = 1
[[analyzers]]
name = "rust"
[analyzers.meta]
msrv = "stable"
[[transformers]]
name = "rustfmt"

94
.github/ISSUE_TEMPLATE/1-bug-report.yml vendored Normal file
View file

@ -0,0 +1,94 @@
name: Bug Report
description: You have an issue with the UAD-ng software itself
title: "bug(scope): "
labels: ["bug"]
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to fill out this bug report!
Wherever you see "If relevant", you can omit the field, if you prefer privacy.
If we believe it's relevant to the bug, we may later ask you to fill the info.
Examples:
- If your OS is Windows or Mac, then [WM](https://en.wikipedia.org/wiki/Window_manager)/[WS](https://en.wikipedia.org/wiki/Windowing_system) and [DE](https://en.wikipedia.org/wiki/Desktop_environment) are irrelevant, because it's implied by the OS.
- If the bug is related to ADB, then it's unlikely to be related to GUI, DE, or WM. No need to specify them.
- If you use the latest-stable official version of any software (such as a [distro](https://en.wikipedia.org/wiki/Linux_distribution)), you can omit the version number.
- type: textarea
id: what-happened
attributes:
label: Describe the bug
description: A clear and concise description of what the bug is, and how to reproduce it
validations:
required: true
- type: textarea
id: expected-behavior
attributes:
label: Expected behavior
description: A clear and concise description of what you expected to happen.
validations:
required: true
- type: textarea
id: suggested-solution
attributes:
label: You have a solution?
description: What to do to fix the issue.
- type: dropdown
id: kernel # technically accurate
attributes:
label: Operating System
options:
- Linux
- MacOS # Darwin+XNU
- Windows # NT
validations:
required: true
- type: input
id: os-v
attributes:
label: Distro version
description: If relevant, please fill it
placeholder: Win11 Home, Debian 12, etc...
- type: input
id: ws-and-wm
attributes:
label: Window System + Manager
description: If relevant, please fill it
placeholder: Wayland 1.23 + Mutter 46, xorg + i3, etc...
- type: input
id: de
attributes:
label: Desktop Environment
description: If relevant, please fill it
placeholder: GNOME 46, KDE Plasma 4, etc...
- type: input
id: adb-v
attributes:
label: ADB version
description: If relevant, please fill it
placeholder: 1.0.41
- type: textarea
id: logfiles
attributes:
label: Provide logs
description: "Paste the relevant (notice the line timestamps) slice (contiguous range) of [the logfile generated by UAD-ng](https://github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation/wiki/FAQ#where-are-the-logfiles)"
value: |
<details><summary>Log</summary>
```
Please replace this line by the log-file contents
```
</details>
- type: checkboxes
id: acknowledgements
attributes:
label: Acknowledgements
description: "Your bug report will be closed if you don't follow the checklist below."
options:
- label: This issue is not a duplicate of an existing bug report.
required: true
- label: I have chosen an appropriate title.
required: true
- label: All requested information has been provided properly.
required: true

View file

@ -0,0 +1,25 @@
name: Feature Request
description: You want a new feature for UAD-ng
title: "feat(scope): "
labels: ["enhancement"]
body:
- type: textarea
id: feature-description
attributes:
label: Describe the feature you want
description: A clear and concise description of the feature you want.
validations:
required: true
- type: checkboxes
id: acknowledgements
attributes:
label: Acknowledgements
description: Your feature request will be closed if you don't follow the checklist below.
options:
- label: This issue is not a duplicate of an existing feature request.
required: true
- label: I have chosen an appropriate title.
required: true
- label: All requested information has been provided properly.
required: true

View file

@ -0,0 +1,56 @@
name: Add new package(s)
description: You want to add new apps to the debloat list
title: "pkg(scope): "
labels: ["package::addition"]
body:
- type: markdown
attributes:
value: |
## Consider submitting a Pull Request
We receive many package-related issues and it's hard to keep up. **Consider submitting a Pull Request yourself**—it helps us process changes much faster! See our [guide on how to contribute](https://github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation/wiki/How-to-contribute) for instructions.
---
## Document each package the best you can
**List**: `Google`|`Misc`|`OEM` (manufacturer) |`AOSP`|`Pending`|`Carrier` (ISP).
**Removal**: `Recommended`|`Advanced`|`Expert`|`Unsafe`. See the [Removal Definitions](https://github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation/wiki/Debloat-Lists#removal-definitions) on the wiki for details. **Please ensure you follow these definitions when proposing changes.**
- type: textarea
id: package-listing
attributes:
label: List your packages
description: Put the package name, list, removal and description of the package. Copy & paste the below default values when adding multiple packages.
value: |
- Package name:
- List:
- Removal:
- Description:
validations:
required: true
- type: checkboxes
id: removal-definitions
attributes:
label: Removal Definitions
description: Please ensure you follow the removal definitions when proposing changes.
options:
- label: I've read the [Removal Definitions](https://github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation/wiki/Debloat-Lists#removal-definitions)
required: true
- type: checkboxes
id: acknowledgements
attributes:
label: Acknowledgements
description: Your bug report will be closed if you don't follow the checklist below.
options:
- label: I removed all those packages on my phone. If not, why? Explain in the issue.
- label: I'm willing to submit a Pull Request for this change.
- label: This issue is not a duplicate of an existing one.
required: true
- label: I have chosen an appropriate title.
required: true
- label: All requested information has been provided properly.
required: true

View file

@ -0,0 +1,47 @@
name: Debloat issue report
description: Your phone has unexpected issues after debloating
title: "pkg(scope): "
labels: ["package::breakage"]
body:
- type: markdown
attributes:
value: |
## Consider submitting a Pull Request
If you know which package caused the issue and how the documentation should be updated, **consider submitting a Pull Request yourself**—it helps us process changes much faster! See our [guide on how to contribute](https://github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation/wiki/How-to-contribute) for instructions.
- type: textarea
id: what-happened
attributes:
label: Describe the problem
description: A clear and concise description of what the problem is, including details (e.g. Android version, phone model)
validations:
required: true
- type: textarea
id: suggested-solution
attributes:
label: You have a solution?
description: What to do to fix the issue.
- type: textarea
id: logfiles
attributes:
label: Provide logs
description: Upload the logfile generated by UAD-ng. See https://github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation/wiki/FAQ#where-are-the-logfiles for the location of logfiles.
validations:
required: true
- type: checkboxes
id: acknowledgements
attributes:
label: Acknowledgements
description: Your bug report will be closed if you don't follow the checklist below.
options:
- label: I'm willing to submit a Pull Request to fix the package documentation.
- label: This issue is not a duplicate of an existing one.
required: true
- label: I have chosen an appropriate title.
required: true
- label: All requested information has been provided properly.
required: true

View file

@ -0,0 +1,58 @@
name: Update apps description or recommendation
description: You want to improve/update a description/recommendation
title: "pkg(scope): "
labels: ["package::documentation"]
body:
- type: markdown
attributes:
value: |
## Consider submitting a Pull Request
We receive many package documentation updates and it's hard to keep up. **Consider submitting a Pull Request yourself**—it helps us process changes much faster! See our [guide on how to contribute](https://github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation/wiki/How-to-contribute) for instructions.
---
## Document each package the best you can
**List**: `Google`|`Misc`|`OEM` (manufacturer) |`AOSP`|`Pending`|`Carrier` (ISP).
**Removal**: `Recommended`|`Advanced`|`Expert`|`Unsafe`. See the [Removal Definitions](https://github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation/wiki/Debloat-Lists#removal-definitions) on the wiki for details. **Please ensure you follow these definitions when proposing changes.**
- type: textarea
id: package-listing
attributes:
label: List your packages
description: Put the package name, list, removal and description of the package. Copy & paste the below default values when adding multiple packages.
value: |
- Package name:
- Current list:
- Proposed list:
- Current removal:
- Proposed removal:
- Current description:
- Proposed description:
validations:
required: true
- type: checkboxes
id: removal-definitions
attributes:
label: Removal Definitions
description: Please ensure you follow the removal definitions when proposing changes.
options:
- label: I've read the [Removal Definitions](https://github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation/wiki/Debloat-Lists#removal-definitions)
required: true
- type: checkboxes
id: acknowledgements
attributes:
label: Acknowledgements
description: Your bug report will be closed if you don't follow the checklist below.
options:
- label: I'm willing to submit a Pull Request for this change.
- label: This issue is not a duplicate of an existing one.
required: true
- label: I have chosen an appropriate title.
required: true
- label: All requested information has been provided properly.
required: true

View file

@ -0,0 +1,25 @@
name: UAD-ng documentation
description: You want to improve the documentation of UAD-ng which is either a Markdown file or the Wiki
title: "docs(scope): "
labels: ["documentation"]
body:
- type: textarea
id: documentation-description
attributes:
label: Describe the documentation you want to change
description: A clear description of what you want to change.
validations:
required: true
- type: checkboxes
id: acknowledgements
attributes:
label: Acknowledgements
description: Your feature request will be closed if you don't follow the checklist below.
options:
- label: This issue is not a duplicate of an existing documentation change request.
required: true
- label: I have chosen an appropriate title.
required: true
- label: All requested information has been provided properly.
required: true

38
.github/ISSUE_TEMPLATE/7-ci.yml vendored Normal file
View file

@ -0,0 +1,38 @@
name: CI/CD
description: File an issue for CI/CD
title: "ci(scope): "
labels: ["ci"]
body:
- type: textarea
attributes:
label: Expected behavior
description: A clear and concise description of what the problem is and how it could be approached.
validations:
required: true
- type: textarea
attributes:
label: Alternate solutions
description: A clear and concise description of any alternative solutions or features you've considered.
validations:
required: false
- type: textarea
attributes:
label: Anything else?
description: |
Links? References? Anything that will give us more context about the issue you are encountering!
Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in.
validations:
required: false
- type: checkboxes
id: acknowledgements
attributes:
label: Acknowledgements
description: Your issue will be closed if you don't follow the checklist below.
options:
- label: This issue is not a duplicate of an existing issue.
required: true
- label: I have chosen an appropriate title.
required: true
- label: All requested information has been provided properly.
required: true

View file

@ -1,34 +0,0 @@
---
name: Add new package(s)
about: You want to add new apps in the debloat list
title: ""
labels: package::addition
assignees: ""
---
**Your phone model:**
**Packages:**
```
com.this.is.a.bad.application
com.this.is.another.bad.application
...
```
- [ ] **I removed all those packages on my phone**
If not why. Leave the brackets blank and explain why.
## Document each package the best you can
**List**: `Google`|`Misc`|`OEM` (manufacturer)|`AOSP`|`Pending`|`Carrier` (isp).
**Removal**: `Recommended`, `Advanced`, `Expert` (this can break important features),
or `Unsafe` (this can bootloop the phone or break extremely important features).
### \<package name\>
**List**: \<list\>
**Removal**: \<recommendation list\>
> Description. Link to its Playstore page if it exists.

View file

@ -1,19 +0,0 @@
---
name: Bug report
about: You have an issue with the UAD software itself
title: ""
labels: bug
assignees: ""
---
**Describe the bug**
A clear and concise description of what the bug is.
**Expected behavior**
A clear and concise description of what you expected to happen.
**You have a solution?**
What to do to fix the issue.
**UAD log**
Upload the logfile generated by UAD.

View file

@ -1 +1 @@
blank_issues_enabled: false
blank_issues_enabled: false

View file

@ -1,18 +0,0 @@
---
name: Debloat issue report
about: Your phone has unexpected issues after debloating
title: ""
labels: package::breakage
assignees: ""
---
**Your phone model**:
**Describe the issue**
A clear and concise description of what the problem is.
**You have a solution?**
What to do to fix the issue.
**UAD log**
Upload the logfile generated by UAD. It would be difficult to help you without it.

View file

@ -1,10 +0,0 @@
---
name: Feature request
about: You want a new feature
title: ""
labels: enhancement
assignees: ""
---
**Describe the feature you want**
A clear description of what you want to happen.

View file

@ -1,37 +0,0 @@
---
name: Update apps description or recommendation
about: You want to improve/update a description/recommendation
title: ""
labels: package::documentation
assignees: ""
---
**Your phone model**:
**Packages documentation to update:**
```
com.this.is.a.application
com.this.is.another.application
...
```
## Documentation Change
**List**: `Google`|`Misc`|`OEM` (manufacturer)|`AOSP`|`Pending`|`Carrier` (isp).
**Removal**: `Recommended`, `Advanced`, `Expert` (this can break important features),
or `Unsafe` (this can bootloop the phone or break extremely important features).
### \<package name\>
**List**: \<current list\> :arrow_right: \<proposed list\>
**Removal**: \<current recommendation list\>
:arrow_right: \<proposed recommendation list\>
### Current description
> Current description
### Proposed description
> Proposed description

31
.github/PULL_REQUEST_TEMPLATE/app.md vendored Normal file
View file

@ -0,0 +1,31 @@
## Description
<!-- Please include a summary of your changes and any relevant context. -->
### Related issues
<!-- Link to related issues using keywords (e.g. Fixes <issue_number>) -->
<!-- Learn more: https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/using-keywords-in-issues-and-pull-requests -->
## How has this been tested?
<!-- Describe the tests you ran to verify your changes. -->
- [ ] Unit tests added/updated
- [ ] Manual testing performed
- [ ] Tested on the following environment(s):
- OS:
- Desktop Environment:
- Window System/Manager:
- ADB version:
- Rust version:
## Checklist
- [ ] I have read the [CONTRIBUTING guidelines](https://github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation/blob/main/CONTRIBUTING.md)
- [ ] My code follows the project's code style
- [ ] I have performed a self-review of my own code
- [ ] I have commented my code, particularly in hard-to-understand areas
- [ ] My changes generate no new warnings
- [ ] I have tested the application with these changes
- [ ] The CI/CD pipeline passes

View file

@ -0,0 +1,18 @@
## Description
<!-- Please describe the documentation changes you're adding or updating. -->
<!-- Link to related issues using keywords (e.g. Fixes <issue_number>) -->
<!-- Learn more: https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/using-keywords-in-issues-and-pull-requests -->
## Documentation Changes
<!-- Briefly describe what documentation was added or modified, and why -->
## Checklist
- [ ] I have read the [CONTRIBUTING guidelines](https://github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation/blob/main/CONTRIBUTING.md)
- [ ] My changes are clear and easy to understand
- [ ] I have checked for grammar and spelling errors
- [ ] I have verified all links are correct
- [ ] I have tested any code examples provided
- [ ] The documentation is properly formatted with markdown

View file

@ -0,0 +1,21 @@
## Description
<!-- Please describe the package changes you're adding or updating. -->
<!-- Link to related issues using keywords (e.g. Fixes <issue_number>) -->
<!-- Learn more: https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/using-keywords-in-issues-and-pull-requests -->
## Testing
- [ ] I have tested these packages on a real device or emulator
- [ ] Package names follow correct naming conventions (e.g., `com.example.app`)
- [ ] Package names have been verified against device/ADB output
- [ ] Descriptions are accurate and helpful
- [ ] No duplicate packages added
## Acknowledgements
- [ ] I have read the [CONTRIBUTING guidelines](https://github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation/blob/main/CONTRIBUTING.md)
- [ ] I have followed the package addition guidelines
- [ ] I have reviewed the [Removal Definitions](https://github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation/wiki/Debloat-Lists#removal-definitions) in the wiki
- [ ] All package information is accurate and tested
- [ ] I understand my PR may be modified before merging

21
.github/pull_request_template.md vendored Normal file
View file

@ -0,0 +1,21 @@
## Description
<!-- Please include a clear summary of the changes in this pull request. -->
## Related issues
<!-- Link to related issues using keywords (e.g. Fixes <issue_number>) -->
<!-- Learn more: https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/using-keywords-in-issues-and-pull-requests -->
## Checklist
- [ ] I have read the [CONTRIBUTING guidelines](https://github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation/blob/main/CONTRIBUTING.md)
- [ ] I have performed a self-review of my changes
- [ ] My changes generate no new warnings
- [ ] The CI/CD pipeline passes (or is expected to pass)
<!--
Optional: specialized templates are kept in .github/PULL_REQUEST_TEMPLATE/
For app/package/documentation-focused PRs, you can use it by including the template in the URL when creating the PR, e.g.
https://github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation/pull/new/<branch_name>?template=app.md, https://github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation/pull/new/<branch_name>?template=package.md or https://github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation/pull/new/<branch_name>?template=documentation.md.
-->

26
.github/release.yml vendored
View file

@ -1,17 +1,23 @@
changelog:
exclude:
labels:
- package::documentation
- package::addition
- package::breakage
- package::bootloop
categories:
- title: Added
labels:
- feature
- title: Changed
- title: Features
labels:
- enhancement
- title: Fixed
labels:
- bug
- title: Refactors
labels:
- refactor
- title: Development
labels:
- ci
- dependencies
- title: Documentation
labels:
- documentation
- title: Packages/apps
labels:
- package::documentation
- package::addition
- package::breakage

View file

@ -5,36 +5,32 @@ on:
jobs:
build:
name: Building ${{ matrix.build_target }} [${{ matrix.graphics }}] [${{ matrix.update_feature }}]
name: Building ${{ matrix.build_target }} [${{ matrix.update_feature }}]
runs-on: ${{ matrix.os }}
strategy:
matrix:
build_target: [linux, macos, windows]
graphics: [glow, wgpu]
build_target: [linux, macos, macos-intel, windows]
update_feature: [self-update, no-self-update]
exclude:
- build_target: windows
update_feature: no-self-update
include:
- build_target: linux
os: ubuntu-latest
os: ubuntu-22.04
- build_target: macos
os: macos-latest
os: macos-15
- build_target: macos-intel
os: macos-15-intel
- build_target: windows
os: windows-latest
- graphics: glow
renderer: "-opengl"
- graphics: wgpu
renderer: "" # Vulkan but we don't want this in the binary filename
os: windows-2022
- update_feature: self-update
update_name: "" # we don't want this in the binary filename
- update_feature: no-self-update
update_name: "-noseflupdate"
update_name: "-noselfupdate"
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: rui314/setup-mold@v1 # faster linker
- uses: actions/cache@v3
- uses: actions/cache@v4
with:
path: |
~/.cargo/bin/
@ -44,22 +40,87 @@ jobs:
target
key: ${{ runner.os }}-release-${{ hashFiles('**/Cargo.lock') }}
restore-keys: ${{ runner.OS }}-release-
if: matrix.os == 'ubuntu-latest'
if: matrix.os == 'ubuntu-22.04'
- name: Building
run: cargo build --release --no-default-features --features ${{ matrix.graphics }},${{ matrix.update_feature }}
- name: Creating ./bin directory
run: mkdir -p bin
run: cargo build --release -p uad-gui --no-default-features --features wgpu,${{ matrix.update_feature }},img
- name: Renaming binaries [Windows]
if: matrix.os == 'windows-latest'
run: mv target/release/uad_gui.exe bin/uad_gui-${{ matrix.build_target }}${{ matrix.renderer }}.exe
if: matrix.os == 'windows-2022'
run: mv target/release/uad-ng.exe uad-ng-${{ matrix.build_target }}.exe
- name: Renaming binaries [Others]
if: matrix.os != 'windows-latest'
run: mv target/release/uad_gui bin/uad_gui${{ matrix.update_name }}-${{ matrix.build_target }}${{ matrix.renderer }}
if: matrix.os != 'windows-2022'
run: mv target/release/uad-ng uad-ng${{ matrix.update_name }}-${{ matrix.build_target }}
- name: Tarball Linux/MacOS binary
if: matrix.os != 'windows-latest'
run: tar -czf bin/uad_gui${{ matrix.update_name }}-${{ matrix.build_target }}${{ matrix.renderer }}{.tar.gz,}
if: matrix.os != 'windows-2022'
run: tar -czf uad-ng${{ matrix.update_name }}-${{ matrix.build_target }}{.tar.gz,}
- name: Install coreutils for macOS
if: startsWith(matrix.os, 'macos')
run: brew install coreutils
- name: Create checksums for binaries and archives [Windows]
if: matrix.os == 'windows-2022'
run: sha256sum uad-ng-${{ matrix.build_target }}.exe | tee uad-ng-${{ matrix.build_target }}.exe-checksum.txt
- name: Create checksums for binaries and archives [Others]
if: matrix.os != 'windows-2022'
run: |
sha256sum uad-ng${{ matrix.update_name }}-${{ matrix.build_target }} | tee uad-ng${{ matrix.update_name }}-${{ matrix.build_target }}-checksum
sha256sum uad-ng${{ matrix.update_name }}-${{ matrix.build_target }}.tar.gz | tee uad-ng${{ matrix.update_name }}-${{ matrix.build_target }}.tar.gz-checksum
- name: Upload artifacts
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: uad_gui${{ matrix.update_name }}-${{ matrix.build_target }}${{ matrix.renderer }}
path: bin/uad_gui-*
name: uad-ng${{ matrix.update_name }}-${{ matrix.build_target }}
path: uad-ng-*
build-cli:
name: Building CLI ${{ matrix.build_target }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
include:
- build_target: linux
os: ubuntu-22.04
- build_target: macos
os: macos-15
- build_target: macos-intel
os: macos-15-intel
- build_target: windows
os: windows-2022
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: actions/cache@v4
with:
path: |
~/.cargo/bin/
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
target
key: ${{ runner.os }}-release-cli-${{ hashFiles('**/Cargo.lock') }}
restore-keys: ${{ runner.OS }}-release-cli-
if: matrix.os == 'ubuntu-22.04'
- name: Building
run: cargo build --release -p uad-cli
- name: Renaming binaries [Windows]
if: matrix.os == 'windows-2022'
run: mv target/release/uad.exe uad-cli-${{ matrix.build_target }}.exe
- name: Renaming binaries [Others]
if: matrix.os != 'windows-2022'
run: mv target/release/uad uad-cli-${{ matrix.build_target }}
- name: Tarball Linux/MacOS binary
if: matrix.os != 'windows-2022'
run: tar -czf uad-cli-${{ matrix.build_target }}{.tar.gz,}
- name: Install coreutils for macOS
if: startsWith(matrix.os, 'macos')
run: brew install coreutils
- name: Create checksums for binaries and archives [Windows]
if: matrix.os == 'windows-2022'
run: sha256sum uad-cli-${{ matrix.build_target }}.exe | tee uad-cli-${{ matrix.build_target }}.exe-checksum.txt
- name: Create checksums for binaries and archives [Others]
if: matrix.os != 'windows-2022'
run: |
sha256sum uad-cli-${{ matrix.build_target }} | tee uad-cli-${{ matrix.build_target }}-checksum
sha256sum uad-cli-${{ matrix.build_target }}.tar.gz | tee uad-cli-${{ matrix.build_target }}.tar.gz-checksum
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: uad-cli-${{ matrix.build_target }}
path: uad-cli-*

View file

@ -2,46 +2,49 @@ name: Continuous Integration
on:
push:
paths:
- "**.rs"
- "Cargo.lock"
- "Cargo.toml"
- "**.json"
- Cargo.lock
- Cargo.toml
- resources/assets/*.ttf
- resources/assets/uad_lists.json
- src/**
pull_request:
paths:
- "**.rs"
- "Cargo.lock"
- "Cargo.toml"
- "**.json"
- Cargo.lock
- Cargo.toml
- resources/assets/*.ttf
- resources/assets/uad_lists.json
- src/**
jobs:
lint:
name: lint
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macOS-latest]
os: [ubuntu-22.04, windows-2022, macos-15]
lint: [check, test, clippy, fmt]
exclude: # https://github.com/community/community/discussions/7835
- os: windows-latest
- os: windows-2022
lint: clippy
- os: windows-latest
- os: windows-2022
lint: fmt
- os: macOS-latest
- os: macos-15
lint: clippy
- os: macOS-latest
- os: macos-15
lint: fmt
include:
- lint: check
args: " --all-features"
env-flag: "-D warnings"
- lint: test
args: ""
- lint: clippy
args: " --all --all-features -- -D warnings"
args: " --all-features -- -D clippy::all -W clippy::style"
- lint: fmt
args: " --all -- --check"
args: " -- --check"
steps:
- uses: actions/checkout@v4
- uses: rui314/setup-mold@v1 # faster linker
- uses: actions/cache@v3
- uses: actions/cache@v4
with:
path: |
~/.cargo/bin/
@ -54,4 +57,25 @@ 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
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- name: Download grcov
run: |
mkdir -p "${HOME}/.local/bin"
curl -sL https://github.com/mozilla/grcov/releases/download/v0.8.19/grcov-x86_64-unknown-linux-gnu.tar.bz2 | tar jxf - -C "${HOME}/.local/bin"
echo "$HOME/.local/bin" >> $GITHUB_PATH
- name: Install LLVM-profdata
run: rustup component add llvm-tools-preview
- name: Run tests
run: CARGO_INCREMENTAL=0 RUSTFLAGS='-Cinstrument-coverage' LLVM_PROFILE_FILE='cargo-test-%p-%m.profraw' cargo test
- name: make coverage directory
run: mkdir ./target/coverage
- name: Run GRCOV
run: grcov . --binary-path ./target/debug/ -s . -t lcov --branch --ignore-not-existing --ignore '../*' --ignore "/*" -o ./target/coverage/tests.lcov

View file

@ -4,49 +4,31 @@ on:
push:
branches:
- main
paths:
- "**.rs"
- "Cargo.lock"
- "Cargo.toml"
tags-ignore:
- dev-build
env:
dev_tag: dev-build
tags:
- v?[0-9]+.[0-9]+.[0-9]+ # semver
- '!dev-build' # not dev-build
jobs:
build:
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
uses: ./.github/workflows/build_artifacts.yml
release:
runs-on: ubuntu-latest
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
runs-on: ubuntu-22.04
needs: build
permissions:
contents: write
steps:
- uses: actions/checkout@v4
- name: Downloads artifacts
uses: actions/download-artifact@v3
uses: actions/download-artifact@v4
- name: Create release
uses: softprops/action-gh-release@v2
with:
path: bin
- name: Create pre-release
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
uses: softprops/action-gh-release@v1
with:
body_path: ${{ github.workspace }}/CHANGELOG.md
files: bin/*/uad_gui-*
prerelease: true
# - name: Update dev-build tag
# if: ${{ github.event_name == 'push' }}
# run: |
# git tag -d ${{ env.dev_tag }} || true
# git push origin :refs/tags/${{ env.dev_tag }} || true
# git tag ${{ env.dev_tag }}
# git push origin ${{ env.dev_tag }}
# - name: Create dev-build release
# if: ${{ github.event_name == 'push' }}
# uses: softprops/action-gh-release@v1
# with:
# generate_release_notes: true
# files: bin/*/uad_gui-*
# prerelease: true
# tag_name: ${{ env.dev_tag }}
files: |
uad-ng-*/*
uad-cli-*/*
generate_release_notes: true
body: |
> [!NOTE]
> 📦 **Package list updates don't require a new app version**—UAD-ng automatically fetches the latest package definitions on launch (requires internet connection).

11
.mailmap Normal file
View file

@ -0,0 +1,11 @@
Rudxain <rudxain@localhost.localdomain>
Rudxain <76864299+Rudxain@users.noreply.github.com> Ricardo Fernández Serrata <76864299+Rudxain@users.noreply.github.com>
Anonymoussaurus <50231698+AnonymousWP@users.noreply.github.com> AnonymousWP <50231698+AnonymousWP@users.noreply.github.com>
Anonymoussaurus <anonymouswp@oxygenupdater.com>
# w1nst0n
# 0x192
# “Frigyes06”
# Frigyes
# Frigyes06
# Frigyes Erdosi-Szucs
# Frigyes Erdosi Szucs

View file

@ -1,223 +0,0 @@
# Changelog
**THIS IS AN UNOFFICIAL FORK**
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
The sections should follow the order `Apps`, `Added`, `Changed`, `Fixed`, `Packaging`
and `Removed`.
## [0.6.2] - Released
### Apps
- [[#65](https://github.com/Universal-Debloater-Alliance/universal-android-debloater/pull/65)] improved package descriptions
- [[#61](https://github.com/Universal-Debloater-Alliance/universal-android-debloater/pull/61)] pkg(`com.samsung.android.providers.contacts`): improve description
- [[#59](https://github.com/Universal-Debloater-Alliance/universal-android-debloater/pull/59)] pkg(`com.qualcomm.qcrilmsgtunnel`): change removal and description
- [[#58](https://github.com/Universal-Debloater-Alliance/universal-android-debloater/pull/58)] pkg(`com.google.android.googlequicksearchbox`): improve description
- [[#39](https://github.com/Universal-Debloater-Alliance/universal-android-debloater/pull/39)] Added new Wi-Fi related packages, custom Bluetooth overlay package, Google system packages, and systemui package
- [[#40](https://github.com/Universal-Debloater-Alliance/universal-android-debloater/pull/40)] Added new package for MediaTek devices and the POCO Launcher resources, IMS Service Entitlement feature, UWB communication feature, Mediatek Duraspeed, and Mediatek Soc Package.
- [[#44](https://github.com/Universal-Debloater-Alliance/universal-android-debloater/pull/44)] Added a lot of new packages
- [[#46](https://github.com/Universal-Debloater-Alliance/universal-android-debloater/pull/46)] Added more packages and updated descriptions
### Fixed
- [[#72](https://github.com/Universal-Debloater-Alliance/universal-android-debloater/pull/72)] Reduced startup window size
### Changed
- [[#71](https://github.com/Universal-Debloater-Alliance/universal-android-debloater/pull/71)] Reversed #18 to only list system packages
## [0.6.1] - Released
### Apps
- [[#21](https://github.com/Universal-Debloater-Alliance/universal-android-debloater/pull/21)] Added android.autoinstalls.config.Xiaomi.model package
- [[#23](https://github.com/Universal-Debloater-Alliance/universal-android-debloater/pull/23)] Modified the description for ASOP camera app.
- [[#25](https://github.com/Universal-Debloater-Alliance/universal-android-debloater/pull/25)] Added and edited packages
- [[#27](https://github.com/Universal-Debloater-Alliance/universal-android-debloater/pull/27)] Added com.android.cellbroadcastreceiver.module
### Fixed
- [[#35](https://github.com/Universal-Debloater-Alliance/universal-android-debloater/pull/35)] OpenGL Drivers
### Changed
- [[#34](https://github.com/Universal-Debloater-Alliance/universal-android-debloater/pull/34)] Updated links to new repo
- [[#26](https://github.com/Universal-Debloater-Alliance/universal-android-debloater/pull/26)] Updated GUI libraries.
## [0.6.0] - Released
### Apps
- [[#13](https://github.com/Universal-Debloater-Alliance/universal-android-debloater/pull/13)] Addedcom.telus.myaccount package.
- [[#15](https://github.com/Universal-Debloater-Alliance/universal-android-debloater/pull/15)] Added More Wiko oem packages.
### Fixed
- [[#14](https://github.com/Universal-Debloater-Alliance/universal-android-debloater/pull/14)] Fixed typos in uad_list.json
- [[#18](https://github.com/Universal-Debloater-Alliance/universal-android-debloater/pull/18)] Fixed ADB command to include all packages, not just system packages. Also fixed uad_list update url.
- TikTok app description.
## [0.5.2] - Released
**WARNING: Settings specification has changed. Previous user settings will be erased**.
### Added
- [[#11](https://github.com/Universal-Debloater-Alliance/universal-android-debloater/pull/11)] All of AnonymousWP's patches. This release notes will probably be restarted as issue counter is reset on fork.
- [[#374](https://github.com/0x192/universal-android-debloater/pull/374)] **Device-specific persistent configuration:** Some settings are now device-specific which means you can maintain different settings across several devices.
- [[#447](https://github.com/0x192/universal-android-debloater/pull/447)] **Backup/Restore the state of a device:** Quick and easy way to save the state of all the system apps on a device and restore it.
- [[#450](https://github.com/0x192/universal-android-debloater/pull/450)] **Warn the user when a work profile is detected:** Displays a warning message when switching to a work profile user and displays unavailable work profile users in the settings.
### Changed
- [[#374](https://github.com/0x192/universal-android-debloater/pull/374)] ALL settings are now persistent.
### Fixed
- [[#448](https://github.com/0x192/universal-android-debloater/pull/448)] UAD crash when interacting with work profiles on recent phones.
### Removed
- The `Export current selection` button and the unintuitive auto import selection (see https://github.com/0x192/universal-android-debloater/issues/192) have been replaced by the new backup/restore system.
## [0.5.1] - 2022-07-03
Since `0.5.0`, all changes related to apps are available to users without downloading a new version of UAD as the software directly download the json debloat list from Github. These changes can be tracked in commits with `[Pkg]` in their name. [See the commits](https://github.com/0x192/universal-android-debloater/commits/main)
### Added
- [[#209](https://github.com/0x192/universal-android-debloater/issues/209)] Persistent highlighting when you click on a package
### Changed
- `neededBy` and `dependencies` field can now list multiple packages (feature not visible in the UI yet)
### Fixed
- [[#286](https://github.com/0x192/universal-android-debloater/issues/286)] UAD stuck on "Downloading UAD lists. Please wait" screen
## Packaging
- [[#256](https://github.com/0x192/universal-android-debloater/issues/256)] Fixed typo in the release name of the noseflupdate variation
- Bump dependencies
## [0.5.0] - 2022-04-03
### Apps
- [[#115](https://github.com/0x192/universal-android-debloater/issues/115)] Added `com.tblenovo.lenovotips` to the recommended list.
- [[#120](https://github.com/0x192/universal-android-debloater/pull/120)] Move Google keyboard to `Advanced` list (Default keyboards should not be in the `Recommended` list)
- [[#169](https://github.com/0x192/universal-android-debloater/issues/154) Move `com.android.htmlviewer` to the `Expert` list. Removing it bootloop the device on MIUI 12.5.4+.
Huge thanks to [@KarlRamstedt](https://github.com/KarlRamstedt) for their help in this major debloat list update:
- [[#122](https://github.com/0x192/universal-android-debloater/pull/122)] Added a bunch of new packages
- [[#122](https://github.com/0x192/universal-android-debloater/pull/122)] A lot of description updates and fixes
- [[#122](https://github.com/0x192/universal-android-debloater/pull/122) | [#138](https://github.com/0x192/universal-android-debloater/pull/138)] Big revision of the recommendations according to more consistent criteria ([see the wiki](https://github.com/0x192/universal-android-debloater/wiki/FAQ#how-are-the-recommendations-chosen))
### Added
- [[#68](https://github.com/0x192/universal-android-debloater/issue/68)] **Unselect all button**: Let's you unselect all the packages you see on screen (i.e in the current filtered list).
- [[#119](https://github.com/0x192/universal-android-debloater/issue/119)] **Reboot button**: Let's you quickly reboot the currently selected device.
- [[#110](https://github.com/0x192/universal-android-debloater/pull/110)] **Remote `uad_lists.json` download**: The debloat list is now directly fetched from the main branch of this repo when you launch UAD. This means there is no longer the need to release a new version of UAD for updating the debloat lists! :rocket:
- [[#121](https://github.com/0x192/universal-android-debloater/pull/121)] :arrows_counterclockwise: **UAD self-update**: UAD will now check at launch if there is a new version of itself and enable you to perform the update directly from the app! :rocket:
### Changed
- [[#165](https://github.com/0x192/universal-android-debloater/issues/165)] UAD now tries every 500ms (for 1min) to initiate an ADB connection until a device is found during the `FindingPhones` loading state.
- All the init process was reworked and a status message is displayed at each stage (`DownloadingList`, `FindingPhones`,`LoadingPackages`,`UpdatingUad` `Ready`) so you know what is happening.
- Minor UI changes
### Packaging
- Add a `no-self-update` build for MacOS and Linux. Useful if UAD is distributed into repositories. The update process will then be managed by a package manager.
- MacOS builds are now also be released as a compressed tarball (like for Linux). You won't need to manually add the executable permission anymore. ([more info](https://github.com/actions/upload-artifact/issues/38))
- Bump dependencies
## [0.4.1] - 2022-01-31
### Fixed
- Selection counter never decreasing.
## [0.4] - 2022-01-30
### Apps
- [[#92](https://github.com/0x192/universal-android-debloater/pull/92)] Added 3 Fairphone packages + 7 Qualcomm packages (thanks [@VeH-c](https://github.com/VeH-c))
- [[#87](https://github.com/0x192/universal-android-debloater/pull/87)] Added 2 Unihertz packages (thanks [@rar0ch](https://github.com/rar0ch))
- [[#52](https://github.com/0x192/universal-android-debloater/issues/52)] Added `uk.co.ee.myee` to the debloat lists (thanks [@lawson58](https://github.com/lawson85)).
- [[#58](https://github.com/0x192/universal-android-debloater/issues/52)] Added `android` to the debloat lists with the tag `Unsafe`.
- Added 2 new Xiaomi packages to the `Recommended` list.
- Multiple package description improvement (thanks [@jonas-ott](https://github.com/jonas-ott) and [@felurx](https://github.com/felurx) for the help)
- Review of the package lists recommendations. The `Recommended` debloat list is now safer (less likely to remove something you'd want to keep).
### Added
- [[#49](https://github.com/0x192/universal-android-debloater/issues/49)] Multi-device support: You are now able to select a device among the list of all ADB connected devices/emulators.
- [[#44](https://github.com/0x192/universal-android-debloater/issues/44)] Persistent settings: Settings (only `theme` for now) are saved to a config file. Its location follows [the standards of the different OS](https://github.com/dirs-dev/dirs-rs#example).
- Links to the Github page, wiki, github issues and logfiles in the `About` page.
### Changed
- [[#65](https://github.com/0x192/universal-android-debloater/issues/65)] ADB commands now run in parallel and asynchronously! This means no more UI freeze when performing long/many actions! :rocket:
- UI now updates itself in real time when performing ADB actions (thanks to async & multithreading). Before, it waited for the end of all actions.
- Logfiles are now located in a more conventional place: [cache_dir](https://docs.rs/dirs/latest/dirs/).
- Previous logs are no longer overwritten. The logger now only appends to the current logfile of the day (UAD_%Y%m%d.log).
- Each new day the logger will create a new file on UAD launch.
- [[#78](https://github.com/0x192/universal-android-debloater/issues/78)] Disable mode is now only available on Android 6+ because the disable ADB commands do not work without root on older devices. The setting will be greyed-out for those devices.
- Minor light theme update
### Fixed
- [[#50](https://github.com/0x192/universal-android-debloater/issues/50)] Resync button flipping theme back to `Lupin`.
- [Regression ([048e7f](https://github.com/0x192/universal-android-debloater/commit/048e7fc8fd6d44b0e8ba933c289249366254a9cc))] Weird disabled/greyed action button with older devices (< Android 8.0). Package could be selected but no action was performed.
- [[#78](https://github.com/0x192/universal-android-debloater/issues/78)] Packages not being actually uninstalled on older devices (< Android 6.0). Without root we can only use `pm block`/`pm unblock` for Android KitKit (4.4) and `pm hide`/`pm unhide` on Android Lollipop (5.x).
### Packaging
- For Arch-based users, UAD is now available in the AUR: `universal-android-debloater-bin` (binary) and `universal-android-debloater` (from source)
- Bump dependencies
## [0.3] - 2021-10-10
### Added
- [[#16](https://github.com/0x192/universal-android-debloater/issues/16)] Multi-user support: You can now debloat/restore apps for any user of the phone (not only the primary user 0).
- `Multi user mode` setting (default to `on` for Android 5+) allowing to remove packages for all users ([a work profile is another user](https://developer.android.com/work/managed-profiles)) instead of only the selected user.
- User switcher (picklist).
- [[#11](https://github.com/0x192/universal-android-debloater/issues/11)] New themes: light, dark and lupin. Lupin theme is now the new default theme. Themes can be changed from the settings.
- [[#40](https://github.com/0x192/universal-android-debloater/issues/40)] Description field scrollbar: you can now scroll long descriptions.
### Fixed
- [Regression] Unsafe packages can be deleted without enabling `expert mode`.
- The refresh button doesn't update settings when a (new) phone is connected.
- [Regression] Restore buttons are disabled when connecting an Android 8.0 phone.
- [[#17](https://github.com/0x192/universal-android-debloater/issues/17)] Refresh icon does not appear.
## [0.2.2] - 2021-09-30
### Fixed
- Crash when connecting a LG device (#33)
## [0.2.1] - 2021-09-28
### Added
- Software version in the navigation panel
### Packaging
- `wgpu` renderer is not the default renderer (you don't need to add `--features wgpu` if you want to build UAD with `wgpu`)
### Fixed
- [[#35](https://github.com/0x192/universal-android-debloater/issues/35)] Exported selection not found
## [0.2] - 2021-09-26
### Added
- [[#2](https://github.com/0x192/universal-android-debloater/issues/2)] UAD now comes with a logger. Debug information will be written to a `uad.log` file (Warning level log in *stdout*)
- [[#15](https://github.com/0x192/universal-android-debloater/issues/15)] Support for older phone (< Android 8.0):
- Disable mode in settings: clear and disable packages instead of uninstalling them (default for old phones because you can't restore uninstalled packages)
- [[#8](https://github.com/0x192/universal-android-debloater/issues/8)] Export your selection in the `uad_exported_selection.txt` file. Packages from this file (if found in the current directory) will be automatically selected upon the start of UAD (or after a refresh).
### Changed
- [[#25](https://github.com/0x192/universal-android-debloater/issues/25)] UAD will no longer crash at start if it doesn't find ADB but will display a useful error message
- [[#3](https://github.com/0x192/universal-android-debloater/issues/3)] Better handling of ADB errors
- Updated dependencies (compatibility with [Iced](https://github.com/iced-rs/iced) main branch latest commit)
- Cleanup and refactoring of the code
- Performance improvement
- Various UI/UX improvement
- The `Debloat/Restore selection` button has been split in 2 buttons: `removing` and `restoring`
### Packaging
- Added an alternative build that uses [OpenGL](https://fr.wikipedia.org/wiki/OpenGL) (instead of [Vulkan](https://fr.wikipedia.org/wiki/Vulkan_(API))) for compatibility with older computers. If you encouter some visual glitches with the default Vulkan build you should try the OpenGL build.
### Fixed
- Spelling mistake
- Failed build with MSVC toolchain

92
CONTRIBUTING.md Normal file
View file

@ -0,0 +1,92 @@
# Contributors Guide
## For who is this guide?
This guide is meant for users who want to contribute to the codebase of Universal Android Debloater Next Generation, whether that is the application code or [the "database"-file for adding packages](https://github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation/wiki/How-to-contribute). To keep all processes streamlined and consistent, we're asking you to stick to this guide whenever contributing.
Even though the guide is made for contributors, it's also strongly recommended that the UAD-ng team sticks to these guidelines. After all, we're a prime example.
## What are the guidelines?
### Mass edits
If you've performed massive edits via automation, you must specify what automation you used. For example, if you ran the command:
```sh
sed -i 's/a/b/' resources/assets/uad_lists.json
```
You should copy-paste that cmd to the pull-request description. This rule applies even if you use "proper" cmds such as `jq`, which safely edit structured data. And it also applies to AI, *especially* LLMs.
This is required so that we can review your big patch without reading it. This improves [transparency](https://en.wikipedia.org/wiki/Transparency_(behavior)), which makes you more trust-worthy! Bonus points if you can provide a sequence of cmds that proves your patch contains exactly what you said it does. For the simple `sed` case, something like:
```sh
# alt: `gh pr checkout 0000 && git checkout main`
git remote add fork https://github.com/user/uadng
git fetch fork
# example commit hash from upstream (not fork);
# more reproducible than branch-name
git checkout beefcafe
sed -i 's/a/b/' resources/assets/uad_lists.json
# compare unstaged change with commit from fork
git diff cafebeef
```
Should be enough.
You should be careful with mass-editing anyways. Even if the verification is successful, the effects [might not be what you expect](https://en.wikipedia.org/wiki/Scunthorpe_problem).
Since AI is non-deterministic, the version number is optional, but it's helpful to know how "intelligent" it is. AI edits are non-reproducible, so "verification scripts" are useless.
### Branching strategy
As for our branching strategy, we're using [Trunk-Based Development](https://trunkbaseddevelopment.com/#one-line-summary).
In short, there's one trunk branch named `main` (`master`). Apart from `main`/`master` there can be different short-lived branches, such as:
- Features (`feature/*`)
- Fixes (`hotfix/*` or simply `fix/*`)
- Dependency updates (`deps/*`)
- Etc.
Do mind that these branch names do only not apply to the addition of packages; for that, we use the following scheme: `[issue number][issue title]`. This can be done [automatically](https://docs.github.com/en/issues/tracking-your-work-with-issues/creating-a-branch-for-an-issue) too.
This is how it looks like and works:
![Trunk-Based Development](https://trunkbaseddevelopment.com/trunk1c.png)
### Syncing branches
If you want to [back-port](https://en.wikipedia.org/wiki/Backporting) (GitHub's "Update" and "Sync" buttons) from upstream `main` to any other branch (for testing purposes, or any other reasonable case), it's recommended that you `rebase` rather than `merge` the changes.
**Don't apply changes to/from arbitrary branches**, that's a recipe for chaos! If you encounter a situation where it's absolutely necessary to sync non-`main` branches, whether to `merge` or `rebase` should be decided by the UAD-ng team (with some contributor feedback) on a case-by-case basis.
### Commit messages
As for commits, we prefer using [Conventional Commit Messages](https://gist.github.com/qoomon/5dfcdf8eec66a051ecd85625518cfd13). When working in any of the branches listed above (if there's an existing issue for it), close it using a [closing keyword](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword). For more information regarding Conventional Commit Messages, see <https://www.conventionalcommits.org/en/v1.0.0/> as well.
### Issue labels
When creating issues, they are automatically labeled based on the [issue template](.github/ISSUE_TEMPLATE/) you choose. These labels help categorize work and generate release notes.
| Label | Purpose | Issue template |
| ----- | ------- | -------------- |
| `bug` | Software bugs in UAD-ng | Bug Report |
| `enhancement` | New feature requests | Feature Request |
| `package::addition` | Adding new packages to the debloat list | Add new package(s) |
| `package::breakage` | Issues caused by debloating | Debloat issue report |
| `package::documentation` | Updating package descriptions or recommendations | Update apps description or recommendation |
| `documentation` | Improvements to docs/wiki | UAD-ng documentation |
| `ci` | CI/CD related issues | CI/CD |
| `refactor` | Code refactoring | — (maintainer-assigned) |
| `dependencies` | Dependency updates | — (maintainer-assigned) |
Labels are also used to automatically generate categorized [release notes](.github/release.yml). Each label maps to a changelog section:
| Label(s) | Changelog category |
| -------- | ------------------ |
| `enhancement` | Features |
| `bug` | Fixed |
| `refactor` | Refactors |
| `package::addition`, `package::breakage`, `package::documentation` | Packages/apps |
| `ci`, `dependencies` | Development |
| `documentation` | Documentation |

5722
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -1,43 +1,63 @@
[package]
name = "uad_gui"
description = "A cross-platform GUI debloater for android devices"
version = "0.6.2"
[workspace]
members = [
"crates/uad-core",
"crates/uad-gui",
"crates/uad-cli"
]
resolver = "2"
[workspace.package]
version = "1.2.0"
authors = ["Universal-Debloater-Alliance"]
license = "GPL-3.0"
homepage = "https://github.com/Universal-Debloater-Alliance/universal-android-debloater"
repository = "https://github.com/Frigyes06/universal-android-debloater"
homepage = "https://github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation"
repository = "https://github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation"
readme = "README.md"
keywords = ["debloater", "android", "adb", "privacy", "bloatware"]
categories = ["gui"]
edition = "2021"
edition = "2024"
[features]
default = ["wgpu", "self-update"]
wgpu = [] # Iced/wgpu is default
glow = ["iced/glow"] # OpenGL support
self-update = ["flate2", "tar"]
no-self-update = []
[dependencies]
[workspace.dependencies]
# Core dependencies
serde = { version = "^1.0", features = ["derive"] }
serde_json = "^1.0"
static_init = "^1.0"
fern = { version = "^0", features = ["colored"] }
chrono = { version = "^0.4", default-features = false, features = ["std", "clock"] }
log = "^0.4"
regex = "^1.10.2"
chrono = { version = "^0.4", default-features = false, features = ["std", "clock"] }
toml = "^0"
dirs = "^5.0.0"
ureq = { version = "*", features = ["json"] }
retry = { version = "^2.0.0" }
iced = "0.9.0"
iced_native = "^0.10.3"
dirs = "^6"
ureq = { version = "3", features = ["json"] }
retry = "^2.0.0"
csv = "^1.3"
[target.'cfg(not(target_os = "windows"))'.dependencies]
flate2 = { version = "^1", optional = true }
tar = { version = "^0.4", optional = true }
# GUI dependencies
iced = { version = "=0.14.0", features = ["advanced"] }
image = "0.25"
rfd = "^0.17.1"
dark-light = "2"
fern = { version = "^0", features = ["colored"] }
[profile.release]
opt-level = "s"
lto = true
strip = "symbols"
# CLI dependencies
clap = { version = "4.6.1", features = ["derive"] }
tokio = { version = "1.52.3", features = ["full"] }
# Platform-specific dependencies
flate2 = "^1"
tar = "^0.4"
win32console = "^0.1.5"
[workspace.lints.rust]
deprecated_safe = "warn"
[workspace.lints.clippy]
undocumented_unsafe_blocks = "forbid"
panic_in_result_fn = "warn"
infinite_loop = "warn"
format_push_string = "warn"
large_include_file = "warn"
shadow_unrelated = "warn"
struct_field_names = "allow" # annoying
disallowed_types = "deny"
disallowed_methods = "deny"
pedantic = { level = "warn", priority = -1 }

View file

@ -631,8 +631,8 @@ to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
Universal Android Debloater GUI
Copyright (C) 2021 W1nst0n
Universal Android Debloater Next Generation
Copyright (C) 2023 Universal Debloater Alliance
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -652,7 +652,7 @@ Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
Universal Android Debloater GUI Copyright (C) 2021 W1nst0n
Universal Android Debloater Next Generation Copyright (C) 2023 Universal Debloater Alliance
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.

217
README.md
View file

@ -1,206 +1,53 @@
# Universal Android Debloater GUI
# Universal Android Debloater Next Generation
**DISCLAIMER**: Use at your own risk. I am not responsible for anything that
could happen to your phone.
> [!warning]
> **DISCLAIMER**: Use at your own risk. We're not responsible for anything that could happen to your devices.
<img src="/resources/screenshots/v0.5.0.png" width="850" alt="uad_screenshot">
<div align=center>
<img width=75% alt="screenshot of apps view" src=./resources/screenshots/v1.0.2.png>
</div>
**This software is still in an early stage of development. Check out the issues, and feel free to contribute!**
This is a detached fork of the [UAD project](https://github.com/0x192/universal-android-debloater). This aims to improve privacy and efficiency (energy, speed, memory) by removing unnecessary and obscure system apps.
This can also improve security by reducing the [attack surface](https://en.wikipedia.org/wiki/Attack_surface). Read [the wiki](https://github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation/wiki) for more details.
## Summary
## Documentation
This is a complete rewrite in Rust of the [UAD project](https://gitlab.com/W1nst0n/universal-android-debloater),
which aims to improve privacy and battery performance by removing unnecessary
and obscure system apps.
This can also contribute to improving security by reducing [the attack surface](https://en.wikipedia.org/wiki/Attack_surface).
Everything about UAD-ng (and related stuff) can be found on the Wiki, such as:
Packages are as well documented as possible to provide a better understanding
of what you can delete or not. The worst issue that could happen is removing
an essential system package needed during boot causing then an unfortunate
bootloop. After about 5 failed system boots, the phone will automatically reboot
in recovery mode, and you'll have to perform a FACTORY RESET. Make a backup first!
- [Getting started](https://github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation/wiki/Getting-started)
- Features of this app
- [Usage guide](https://github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation/wiki/Usage)
- Suggested Android app replacements
- How to get the cutting-edge version by [building the source-code](https://github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation/wiki/Building-from-source)
- Weird things OEMs do
- [Suggested apps for analyzing APKs](https://github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation/wiki/How-to-contribute#useful-apps)
In any case, you **CANNOT** brick your device with this software!
That's the main point, right?
## Privacy
## Features
UAD-ng does not collect or transmit any user data. The only external connections are `GET` requests to GitHub for fetching the [package list](https://github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation/blob/main/resources/assets/uad_lists.json) ([src/core/uad_lists.rs](src/core/uad_lists.rs)) and checking for updates ([src/core/update.rs](src/core/update.rs)).
- [x] Uninstall/Disable and Restore/Enable system packages
- [x] Multi-user support (e.g. apps in work profiles)
- [x] Export/Import your selection in `uad_exported_selection.txt`
- [x] Multi-device support: you can connect multiple phones at the same time
- [x] All your actions are logged, so you never forget what you've done
## Contact
NB : System apps cannot truly be uninstalled without root (see the [FAQ](https://github.com/Universal-Debloater-Alliance/universal-android-debloater/wiki/FAQ))
**For real-time communication and support, consider joining our Discord guild:**
## Universal Debloat Lists
[<img width=64em alt="Discord symbol" src=./resources/images/icon_clyde_blurple.svg>](https://discord.gg/CzwbMCPEZa)
- [x] GFAM (Google/Facebook/Amazon/Microsoft)
- [x] AOSP
- [x] Manufacturers (OEM)
- [x] Mobile carriers
- [x] Qualcomm / Mediatek / Miscellaneous
**If you prefer using Matrix, we have a bridge to Discord:**
## Manufacturers debloat lists
* [ ] Archos
* [X] Asus
* [ ] Blackberry
* [X] Fairphone
* [ ] Gionee
* [X] Google
* [x] Honor
* [ ] HTC
* [X] Huawei
* [X] iQOO
* [X] LG
* [X] Lenovo
* [X] Motorola
* [X] Nokia
* [X] Nubia
* [X] Nothing Phone
* [X] OnePlus
* [X] Oppo
* [X] Realme
* [X] Samsung
* [X] Sony
* [X] Tecno
* [X] TCL
* [X] Unihertz
* [X] Vivo/iQOO
* [X] Wiko
* [X] Xiaomi
* [X] ZTE
[<img width=64em src=https://matrix.org/images/matrix-favicon.svg>](https://matrix.to/#/#uad-ng:matrix.org)
## Mobile carriers debloat lists
## Friends
| Country | Carriers |
| ------- | ------------------------------- |
| France | Orange, SFR, Free, Bouygues |
| USA | T-Mobile, Verizon, Sprint, AT&T |
| Germany | Telekom |
| UK | EE |
Several projects integrate with or depend on UAD-ng's data and tools:
## How to use it
- **[Canta](https://github.com/samolego/Canta)** — A mobile Android debloater that uses Shizuku for rootless privilege escalation. It integrates with UAD-ng's Universal Debloat List to provide safe package recommendations without requiring a PC.
- **Read the [FAQ](https://github.com/Universal-Debloater-Alliance/universal-android-debloater/wiki/FAQ)!**
- **Do a proper backup of your data! You can never be too careful!**
- Enable _Developer Options_ on your smartphone.
- Turn on _USB Debugging_ from the developer panel.
- From the settings, disconnect from any OEM accounts (when you delete an OEM
account package it could lock you on the lock screen because the phone can't
associate your identity anymore)
- Install ADB (see the instructions by clicking on your OS below):
<p>
<details>
<summary>LINUX</summary>
- Install _Android platform tools_ on your PC :
Debian Base:
```bash
sudo apt install android-sdk-platform-tools
```
Arch-Linux Base:
```bash
sudo pacman -S android-tools
```
Red Hat Base:
```bash
sudo yum install android-tools
```
OpenSUSE Base:
```bash
sudo zypper install android-tools
```
Gentoo Base:
```bash
sudo emerge -av dev-util/android-tools
```
NixOS Base:
```bash
sudo nix-shell -p android-tools
```
Alpine Linux or FreeBSD Base:
```bash
sudo pkg install android-tools
```
Fedora Base:
```bash
sudo dnf install android-tools
```
Replace sudo with doas depending on what you use
</details>
</p>
<p>
<details>
<summary>MAC OS</summary>
- Install [Homebrew](https://brew.sh/)
- Install _Android platform tools_
```bash
brew install android-platform-tools
```
</details>
</p>
<p>
<details>
<summary>WINDOWS</summary>
- Download [android platform tools](https://dl.google.com/android/repository/platform-tools-latest-windows.zip)
and unzip it somewhere.
- [Add the android platform tools to your PATH](https://www.architectryan.com/2018/03/17/add-to-the-path-on-windows-10/)
**OR** make sure to launch UAD from the same directory.
- [Install USB drivers for your device](https://developer.android.com/studio/run/oem-usb#Drivers)
- Check your device is detected:
```bash
adb devices
```
</details>
</p>
- Download the latest release of UAD GUI for your Operating System [here](https://github.com/Universal-Debloater-Alliance/universal-android-debloater/releases). Take the `opengl` version only if the default version (with a Vulkan backend) doesn't launch.
**NOTE:** Chinese phone users may need to use the AOSP list to remove some stock
apps because those Chinese manufacturers (especially Xiaomi and Huawei) have been
using the name of AOSP packages for their own (modified & closed-source) apps.
**IMPORTANT NOTE:** You will have to run this software whenever your OEM pushes
an update to your phone as some _uninstalled_ system apps could be reinstalled.
## How to contribute
Hey-hey-hey! Don't go away so fast! This is a community project.
That means I need you! I'm sure you want to make this project better anyway.
==> [How to contribute](https://github.com/Universal-Debloater-Alliance/universal-android-debloater/wiki)
- **Projects by [Muntashir Akon](https://github.com/MuntashirAkon):**
- **[AppManager](https://github.com/MuntashirAkon/AppManager)** — An advanced Android app manager with powerful debloating features.
- **[android-debloat-list](https://github.com/MuntashirAkon/android-debloat-list)** — A comprehensive, community-driven list of Android packages to debloat, based on UAD-ng's list.
## Special thanks
- [@mawilms](https://github.com/mawilms) for his LotRO plugin manager ([Lembas](https://github.com/mawilms/lembas))
which helped me a lot to understand how to use the [Iced](https://github.com/hecrj/iced)
GUI library.
- [@0x192](https://github.com/0x192) who created the original UAD project.
- [@mawilms](https://github.com/mawilms) for his LotRO plugin manager ([Lembas](https://github.com/mawilms/lembas)) which helped a lot to understand how to use the [Iced](https://github.com/iced-rs/iced) GUI library.
- [@casperstorm](https://github.com/casperstorm) for the UI/UX inspiration.

38
RELEASE.md Normal file
View file

@ -0,0 +1,38 @@
# Release management
## Semantic versioning
We're making use of [semantic versioning](https://semver.org/). We use semantic versioning for two things:
1. GitHub Milestones
1. UAD-ng releases
Speaking of milestones: it could be that we have a bug-fix release (e.g. 1.0.3), but a contributor submits a PR that adds a new feature. What do we do? Merge after we released 1.0.3? Change the name of the milestone to for example 1.1.0? Or another approach?
In that case, we should closely review the PR and 'compare' it with what semantic versioning has to say about the submitted feature. If the changes are significant enough, we're renaming the milestone to (for example) 1.1.0.
## Checklist before releasing a new version
- [ ] Make sure the Milestone is completed and if not, check what needs to be done to complete it.
- [ ] Make sure all merged PRs regarding the application follow the Conventional Commit Messages style. This makes sure that when generating a changelog, the changes look consistent, which in turn improves readability.
- [ ] Make sure all merged PRs have the correct labels assigned, as the changelog is generated based on labels.
- [ ] Create a release preparation PR that bumps the UAD-ng version in `Cargo.toml` and `Cargo.lock`.
When all the above has been checked, you can push a tag to `main` to trigger the GitHub Action that creates a release:
- Create the tag: `git tag -s v1.2.3 -am '1.2.3'`
- Push the tag: `git push origin v1.2.3`
Change the version number to whatever version we're releasing.
## Development process
1. Update dependencies right after a new release, so that we start a new milestone with updated dependencies
1. On-going development of bug-fixes and new features etc, along with fixing potential bugs, potentially due to the updated dependencies
1. Release
## Faulty releases
If we publish a faulty release, for example containing a critical bug, this is how we should deal with it:
We issue a hotfix and keep the faulty release but we'll add warnings to the faulty release in the changelog.

11
build.rs Normal file
View file

@ -0,0 +1,11 @@
const META: &str = "resources/assets/manifest.rc";
fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("cargo::rerun-if-changed={META}");
if std::env::var("CARGO_CFG_TARGET_FAMILY")? == "windows" {
embed_resource::compile(META, embed_resource::NONE)
.manifest_optional()
.unwrap();
}
Ok(())
}

7
clippy.toml Normal file
View file

@ -0,0 +1,7 @@
disallowed-types = [
{ path = "iced::widget::Text", reason = "Use [`crate::gui::widgets::text`] instead. For further details, see #523 and #858" },
]
disallowed-methods= [
{ path = "iced::widget::text", reason = "Use [`crate::gui::widgets::text`] instead. For further details, see #523 and #858" },
]

52
crates/uad-cli/Cargo.toml Normal file
View file

@ -0,0 +1,52 @@
[package]
name = "uad-cli"
version.workspace = true
authors.workspace = true
license.workspace = true
homepage.workspace = true
repository.workspace = true
readme.workspace = true
keywords.workspace = true
categories = ["command-line-utilities"]
edition.workspace = true
[[bin]]
name = "uad"
path = "src/main.rs"
[dependencies]
uad-core = { path = "../uad-core" }
clap.workspace = true
clap_complete = "4.4"
tokio.workspace = true
serde.workspace = true
serde_json.workspace = true
log.workspace = true
chrono.workspace = true
toml.workspace = true
dirs.workspace = true
ureq.workspace = true
retry.workspace = true
csv.workspace = true
rustyline = "14.0"
[lints.rust]
deprecated_safe = "warn"
[lints.clippy]
undocumented_unsafe_blocks = "deny"
exit = "deny"
panic_in_result_fn = "warn"
infinite_loop = "warn"
mem_forget = "warn"
implicit_clone = "warn"
format_push_string = "warn"
large_include_file = "warn"
shadow_unrelated = "warn"
struct_field_names = "allow" # annoying
disallowed_types = "deny"
disallowed_methods = "deny"
allow_attributes_without_reason = "warn"
pedantic = { level = "warn", priority = -1 }

View file

@ -0,0 +1,44 @@
#!/usr/bin/env bash
# Example usage script for UAD CLI
# Check if uad-cli is available
if ! command -v uad &> /dev/null; then
echo "uad command not found. Please build and install uad-cli first."
exit 1
fi
echo "=== UAD CLI Usage Examples ==="
echo
echo "1. List connected devices:"
uad devices
echo
echo "2. List all enabled packages:"
uad list --state enabled | head -20
echo "... (showing first 20)"
echo
echo "3. Search for Google packages:"
uad list --search google | head -10
echo "... (showing first 10)"
echo
echo "4. Show info about a package (example):"
echo "uad info com.google.android.gms"
echo
echo "5. Dry-run uninstall (safe to test):"
echo "uad uninstall com.example.package --dry-run"
echo
echo "6. Start interactive mode:"
echo "uad repl"
echo
echo "=== Generate shell completions ==="
echo "For bash: uad completions bash > ~/.local/share/bash-completion/completions/uad"
echo "For zsh: uad completions zsh > ~/.local/share/zsh/site-functions/_uad"
echo "For fish: uad completions fish > ~/.config/fish/completions/uad.fish"

View file

@ -0,0 +1,470 @@
use clap::CommandFactory;
use clap_complete::{Shell, generate};
use std::collections::{HashMap, HashSet};
use std::io::Write;
use uad_core::adb::{ACommand, PmListPacksFlag};
use uad_core::sync::{
CorePackage, Phone, User, apply_pkg_state_commands, get_devices_list, get_package_state,
run_adb_shell_action,
};
use uad_core::uad_lists::{Package, PackageState, Removal, UadList, load_debloat_lists};
use uad_core::utils::{matches_search, truncate_description};
use crate::device::{NO_DEVICES_FOUND, get_target_device, get_user};
use crate::filters::{ListFilter, RemovalFilter, StateFilter};
use crate::{Cli, print_or_exit, println_or_exit};
/// List all connected Android devices
pub fn list_devices() -> Result<(), Box<dyn std::error::Error>> {
println_or_exit!("Scanning for connected devices...");
let devices = get_devices_list();
if devices.is_empty() {
return Err(NO_DEVICES_FOUND.into());
}
println_or_exit!("\nFound {} device(s):\n", devices.len());
for device in &devices {
println_or_exit!(" Model: {}", device.model);
println_or_exit!(" Serial: {}", device.adb_id);
println_or_exit!(" Android SDK: {}", device.android_sdk);
if !device.user_list.is_empty() {
println_or_exit!(" Users: {} user(s)", device.user_list.len());
for user in &device.user_list {
let protected = if user.protected { " (protected)" } else { "" };
println_or_exit!(" - User ID: {}{}", user.id, protected);
}
}
println_or_exit!();
}
Ok(())
}
/// Context for package filtering and display
pub struct PackageListContext {
pub state_filter: Option<StateFilter>,
pub removal_filter: Option<RemovalFilter>,
pub list_filter: Option<ListFilter>,
pub search: Option<String>,
}
impl PackageListContext {
/// Check if package passes all filters
pub fn filter_package(
&self,
pkg_name: &str,
pkg_info: Option<&Package>,
pkg_state: PackageState,
) -> bool {
// Removal filter
if let Some(removal) = self.removal_filter {
if !removal.matches(pkg_info) {
return false;
}
}
// State filter
if let Some(state) = self.state_filter {
if !state.matches(pkg_state) {
return false;
}
}
// List filter
if let Some(list) = self.list_filter {
if !list.matches(pkg_info) {
return false;
}
}
// Search filter
if let Some(ref search_term) = self.search {
let description = pkg_info.map(|p| p.description.as_str());
if !matches_search(pkg_name, search_term, description) {
return false;
}
}
true
}
/// Determine what information to show based on active filters
pub fn display_config(&self) -> DisplayConfig {
DisplayConfig {
show_state: self.state_filter.is_none_or(|f| !f.is_specific()),
show_removal: self.removal_filter.is_none_or(|f| !f.is_specific()),
}
}
}
pub struct DisplayConfig {
pub show_state: bool,
pub show_removal: bool,
}
/// List packages on a device with filtering
pub fn list_packages(
device: Option<String>,
state_filter: Option<StateFilter>,
removal_filter: Option<RemovalFilter>,
list_filter: Option<ListFilter>,
search: Option<String>,
user_id: Option<u16>,
) -> Result<(), Box<dyn std::error::Error>> {
let target_device = get_target_device(device)?;
let uad_lists = load_debloat_lists(false).unwrap_or_else(|lists| lists);
println_or_exit!(
"Listing packages on: {} ({})\n",
target_device.model,
target_device.adb_id
);
let context = PackageListContext {
state_filter,
removal_filter,
list_filter,
search,
};
let pm_flag = state_filter.and_then(StateFilter::to_pm_flag);
let system_packages = ACommand::new()
.shell(&target_device.adb_id)
.pm()
.list_packages_sys(pm_flag, user_id)?;
let displayed_count = display_package_list(
&system_packages,
&uad_lists,
&target_device.adb_id,
user_id,
&context,
)?;
if displayed_count == 0 {
println_or_exit!(" No packages found matching the specified filters.");
} else {
println_or_exit!("\nTotal: {} package(s)", displayed_count);
}
Ok(())
}
/// Display a list of packages with their info
pub fn display_package_list(
packages: &[String],
uad_lists: &HashMap<String, Package>,
device_serial: &str,
user_id: Option<u16>,
context: &PackageListContext,
) -> Result<usize, Box<dyn std::error::Error>> {
let config = context.display_config();
let mut displayed_count = 0;
let enabled_packages: HashSet<String> = ACommand::new()
.shell(device_serial)
.pm()
.list_packages_sys(Some(PmListPacksFlag::OnlyEnabled), user_id)
.unwrap_or_default()
.into_iter()
.collect();
let disabled_packages: HashSet<String> = ACommand::new()
.shell(device_serial)
.pm()
.list_packages_sys(Some(PmListPacksFlag::OnlyDisabled), user_id)
.unwrap_or_default()
.into_iter()
.collect();
for pkg_name in packages {
let pkg_info = uad_lists.get(pkg_name);
let pkg_state = if enabled_packages.contains(pkg_name) {
PackageState::Enabled
} else if disabled_packages.contains(pkg_name) {
PackageState::Disabled
} else {
PackageState::Uninstalled
};
if !context.filter_package(pkg_name, pkg_info, pkg_state) {
continue;
}
display_package_entry(pkg_name, pkg_info, pkg_state, &config);
displayed_count += 1;
}
Ok(displayed_count)
}
/// Display a single package entry
pub fn display_package_entry(
pkg_name: &str,
pkg_info: Option<&Package>,
pkg_state: PackageState,
config: &DisplayConfig,
) {
print_or_exit!("[");
if let Some(info) = pkg_info {
if config.show_removal {
print_or_exit!("{}", info.removal);
if config.show_state {
print_or_exit!(" - ");
}
}
if config.show_state {
print_or_exit!("{}", pkg_state);
}
print_or_exit!("] {}", pkg_name);
if !info.description.is_empty() {
print_or_exit!(" - {}", truncate_description(&info.description, 80));
}
} else {
if config.show_removal {
print_or_exit!("Unlisted");
if config.show_state {
print_or_exit!(" - ");
}
}
if config.show_state {
print_or_exit!("{}", pkg_state);
}
print_or_exit!("] {}", pkg_name);
}
println_or_exit!();
}
/// Change the state of one or more packages
pub fn change_package_state(
packages: &[String],
device: Option<String>,
user_id: Option<u16>,
dry_run: bool,
target_state: PackageState,
action_name: &str,
) -> Result<(), Box<dyn std::error::Error>> {
if packages.is_empty() {
return Err("No packages specified".into());
}
let target_device = get_target_device(device)?;
let user = get_user(&target_device, user_id)?;
let uad_lists = load_debloat_lists(false).unwrap_or_else(|lists| lists);
println!(
"{} {} package(s) on: {} ({})\n",
action_name,
packages.len(),
target_device.model,
target_device.adb_id
);
if dry_run {
println!("DRY RUN - No changes will be made\n");
}
for pkg_name in packages {
process_package_state_change(
pkg_name,
&target_device,
user,
target_state,
dry_run,
&uad_lists,
)?;
println!();
}
if dry_run {
println!("Dry run completed. No changes were made.");
} else {
println!("Operation completed successfully.");
}
Ok(())
}
/// Process state change for a single package
fn process_package_state_change(
pkg_name: &str,
device: &Phone,
user: User,
target_state: PackageState,
dry_run: bool,
uad_lists: &HashMap<String, Package>,
) -> Result<(), Box<dyn std::error::Error>> {
let current_state = get_package_state(&device.adb_id, pkg_name, Some(user.id))
.ok_or("Package not found on device")?;
println!(" {} ({})", pkg_name, current_state);
if current_state == target_state {
println!(" → Already in target state, skipping");
return Ok(());
}
let pkg_info = uad_lists.get(pkg_name);
if let Some(info) = pkg_info {
if info.removal == Removal::Unsafe {
println!(" ⚠ WARNING: This package is marked as UNSAFE to remove!");
}
}
let core_pkg = CorePackage {
name: pkg_name.to_string(),
description: pkg_info.map(|p| p.description.clone()).unwrap_or_default(),
removal: pkg_info.map(|p| p.removal).unwrap_or(Removal::Unlisted),
state: current_state,
list: pkg_info.map(|p| p.list).unwrap_or(UadList::Unlisted),
};
let commands = apply_pkg_state_commands(&core_pkg, target_state, user, device);
if dry_run {
for cmd in &commands {
println!(" Would run: {}", cmd);
}
} else {
execute_with_fallback(
pkg_name,
target_state,
&core_pkg,
user,
device,
&commands,
" ",
)?;
}
Ok(())
}
/// Execute commands and verify package state with fallback
pub fn execute_with_fallback(
package: &str,
target_state: PackageState,
core_pkg: &CorePackage,
user: User,
device: &Phone,
commands: &[String],
indent: &str,
) -> Result<(), Box<dyn std::error::Error>> {
// Capture the before-state of packages on other users for cross-user detection
let before_cross_user_states =
uad_core::sync::capture_cross_user_states(package, &device.adb_id, user.id, device);
// Execute commands
for cmd in commands {
match run_adb_shell_action(&device.adb_id, cmd.as_str()) {
Ok(_) => println!("{}{}", indent, cmd),
Err(e) => {
return Err(format!("{indent}✗ Failed to execute `{cmd}`: {e:?}").into());
}
}
}
// Verify package state and attempt fallback if needed
let actual_state = match get_package_state(&device.adb_id, package, Some(user.id)) {
Some(state) => state,
None if target_state == PackageState::Uninstalled => PackageState::Uninstalled,
None => {
return Err(format!(
"Package '{package}' was not found on device for user {}",
user.id
)
.into());
}
};
if actual_state != target_state {
println!(
"{}⚠ Package state verification failed: expected {:?}, got {:?}",
indent, target_state, actual_state
);
// Attempt fallback
if let Ok(fallback_action) =
uad_core::sync::attempt_fallback(core_pkg, target_state, actual_state, user, device)
{
println!("{}↻ Fallback: {}", indent, fallback_action);
} else {
println!("{}✗ No fallback available", indent);
}
}
// Check for cross-user behavior if operation succeeded
if actual_state == target_state {
if let Some(notification) = uad_core::sync::detect_cross_user_behavior(
package,
device.adb_id.as_str(),
user.id,
target_state,
actual_state,
device,
&before_cross_user_states,
) {
println!("{} {}", indent, notification);
}
}
Ok(())
}
/// Show detailed information about a package
pub fn show_package_info(
package: &str,
device: Option<String>,
user_id: Option<u16>,
) -> Result<(), Box<dyn std::error::Error>> {
println!("Package: {}\n", package);
let uad_lists = load_debloat_lists(false).unwrap_or_else(|lists| lists);
if let Some(pkg_info) = uad_lists.get(package) {
println!("UAD Information:");
println!(" List: {}", pkg_info.list);
println!(" Removal: {}", pkg_info.removal);
println!(" Description: {}", pkg_info.description);
println!();
} else {
println!(" Not found in UAD lists (unlisted package)\n");
}
if let Some(device_id) = device {
let target_device = get_target_device(Some(device_id))?;
let user = get_user(&target_device, user_id)?;
println!("Device: {} ({})", target_device.model, target_device.adb_id);
println!("User: {}", user.id);
let state = get_package_state(&target_device.adb_id, package, Some(user.id))
.ok_or("Package not found on device")?;
println!(" State: {}", state);
}
Ok(())
}
/// Update UAD package lists from remote repository
pub fn update_lists() -> Result<(), Box<dyn std::error::Error>> {
println!("Updating UAD package lists from remote repository...");
match load_debloat_lists(true) {
Ok(_lists) => {
println!("✓ Successfully updated package lists");
Ok(())
}
Err(_lists) => Err("Failed to update lists from remote, using cached version".into()),
}
}
/// Generate shell completion script
pub fn generate_completions(shell: Shell) {
let mut cmd = Cli::command();
let name = cmd.get_name().to_string();
generate(shell, &mut cmd, name, &mut std::io::stdout());
}

View file

@ -0,0 +1,47 @@
use uad_core::sync::{Phone, User, get_devices_list};
pub const NO_DEVICES_FOUND: &str =
"No devices found. Make sure ADB is installed and devices are connected.";
/// Get target device, either by serial or first available
pub fn get_target_device(device: Option<String>) -> Result<Phone, Box<dyn std::error::Error>> {
let devices = get_devices_list();
if devices.is_empty() {
return Err(NO_DEVICES_FOUND.into());
}
let target_device = if let Some(device_id) = device {
devices
.iter()
.find(|d| d.adb_id == device_id)
.ok_or("Device not found")?
.clone()
} else {
if devices.len() > 1 {
eprintln!(
"Warning: Multiple devices found, using first one: {}",
devices[0].adb_id
);
}
devices[0].clone()
};
Ok(target_device)
}
/// Get user from device, creating a basic one if not found
pub fn get_user(device: &Phone, user_id: Option<u16>) -> Result<User, Box<dyn std::error::Error>> {
let uid = user_id.unwrap_or(0);
if let Some(user) = device.user_list.iter().find(|u| u.id == uid) {
Ok(*user)
} else {
// Create a basic user if not found in list
Ok(User {
id: uid,
index: 0,
protected: false,
})
}
}

View file

@ -0,0 +1,98 @@
use clap::ValueEnum;
use uad_core::adb::PmListPacksFlag;
use uad_core::uad_lists::{Package, PackageState, Removal, UadList};
#[derive(Debug, Clone, Copy, ValueEnum)]
pub enum StateFilter {
/// Show all packages regardless of state
All,
/// Show only enabled packages
Enabled,
/// Show only disabled packages
Disabled,
/// Show only uninstalled packages
Uninstalled,
}
#[derive(Debug, Clone, Copy, ValueEnum)]
pub enum RemovalFilter {
All,
Recommended,
Advanced,
Expert,
Unsafe,
Unlisted,
}
#[derive(Debug, Clone, Copy, ValueEnum)]
pub enum ListFilter {
All,
Aosp,
Carrier,
Google,
Misc,
Oem,
Pending,
Unlisted,
}
impl StateFilter {
pub fn to_pm_flag(self) -> Option<PmListPacksFlag> {
match self {
Self::Enabled => Some(PmListPacksFlag::OnlyEnabled),
Self::Disabled => Some(PmListPacksFlag::OnlyDisabled),
Self::Uninstalled | Self::All => Some(PmListPacksFlag::IncludeUninstalled),
}
}
pub fn matches(self, pkg_state: PackageState) -> bool {
match self {
Self::All => true,
Self::Enabled => pkg_state == PackageState::Enabled,
Self::Disabled => pkg_state == PackageState::Disabled,
Self::Uninstalled => pkg_state == PackageState::Uninstalled,
}
}
pub fn is_specific(self) -> bool {
matches!(self, Self::Enabled | Self::Disabled | Self::Uninstalled)
}
}
impl RemovalFilter {
pub fn matches(self, pkg_info: Option<&Package>) -> bool {
match pkg_info {
Some(info) => match self {
Self::All => true,
Self::Recommended => info.removal == Removal::Recommended,
Self::Advanced => info.removal == Removal::Advanced,
Self::Expert => info.removal == Removal::Expert,
Self::Unsafe => info.removal == Removal::Unsafe,
Self::Unlisted => info.removal == Removal::Unlisted,
},
None => matches!(self, Self::All | Self::Unlisted),
}
}
pub fn is_specific(self) -> bool {
!matches!(self, Self::All)
}
}
impl ListFilter {
pub fn matches(self, pkg_info: Option<&Package>) -> bool {
match pkg_info {
Some(info) => match self {
Self::All => true,
Self::Aosp => info.list == UadList::Aosp,
Self::Carrier => info.list == UadList::Carrier,
Self::Google => info.list == UadList::Google,
Self::Misc => info.list == UadList::Misc,
Self::Oem => info.list == UadList::Oem,
Self::Pending => info.list == UadList::Pending,
Self::Unlisted => info.list == UadList::Unlisted,
},
None => matches!(self, Self::All | Self::Unlisted),
}
}
}

251
crates/uad-cli/src/main.rs Normal file
View file

@ -0,0 +1,251 @@
#![allow(
clippy::needless_continue,
clippy::collapsible_if,
clippy::uninlined_format_args,
clippy::map_unwrap_or,
clippy::unnecessary_wraps,
reason = "Suppress non-critical pedantic/style lints to keep build green"
)]
use clap::{Parser, Subcommand};
use clap_complete::Shell;
use std::process::ExitCode;
use uad_core::uad_lists::PackageState;
mod commands;
mod device;
mod filters;
mod output;
mod repl;
use filters::{ListFilter, RemovalFilter, StateFilter};
#[derive(Parser)]
#[command(name = "uad")]
#[command(about = "Universal Android Debloater - Command Line Interface", long_about = None)]
#[command(version)]
#[command(propagate_version = true)]
pub struct Cli {
#[command(subcommand)]
command: Commands,
}
#[derive(Subcommand)]
enum Commands {
/// List connected Android devices
Devices,
/// List packages on a device
#[command(name = "list", visible_alias = "ls")]
List {
/// Device serial number (optional, uses first device if not specified)
#[arg(short, long)]
device: Option<String>,
/// Filter by package state
#[arg(short, long, value_enum)]
state: Option<StateFilter>,
/// Filter by removal category
#[arg(short, long, value_enum)]
removal: Option<RemovalFilter>,
/// Filter by UAD list
#[arg(short, long, value_enum)]
list: Option<ListFilter>,
/// Search pattern (matches package name or description)
#[arg(short = 'q', long)]
search: Option<String>,
/// User ID (defaults to 0)
#[arg(short, long)]
user: Option<u16>,
},
/// Uninstall packages (default removal action)
#[command(visible_alias = "rm")]
Uninstall {
/// Package names to uninstall
packages: Vec<String>,
/// Device serial number (optional, uses first device if not specified)
#[arg(short, long)]
device: Option<String>,
/// User ID (defaults to 0)
#[arg(short, long)]
user: Option<u16>,
/// Dry run - show what would be done without actually doing it
#[arg(long)]
dry_run: bool,
},
/// Restore (reinstall) packages
#[command(visible_alias = "restore")]
Enable {
/// Package names to restore/enable
packages: Vec<String>,
/// Device serial number (optional, uses first device if not specified)
#[arg(short, long)]
device: Option<String>,
/// User ID (defaults to 0)
#[arg(short, long)]
user: Option<u16>,
/// Dry run - show what would be done without actually doing it
#[arg(long)]
dry_run: bool,
},
/// Disable packages (keeps data but prevents execution)
Disable {
/// Package names to disable
packages: Vec<String>,
/// Device serial number (optional, uses first device if not specified)
#[arg(short, long)]
device: Option<String>,
/// User ID (defaults to 0)
#[arg(short, long)]
user: Option<u16>,
/// Dry run - show what would be done without actually doing it
#[arg(long)]
dry_run: bool,
},
/// Show detailed information about a package
Info {
/// Package name
package: String,
/// Device serial number (optional, uses first device if not specified)
#[arg(short, long)]
device: Option<String>,
/// User ID (defaults to 0)
#[arg(short, long)]
user: Option<u16>,
},
/// Update UAD package lists from remote repository
Update,
/// Generate shell completion script
Completions {
/// Shell to generate completions for
#[arg(value_enum)]
shell: Shell,
},
/// Start interactive REPL mode
#[command(visible_alias = "shell")]
Repl {
/// Device serial number (optional, uses first device if not specified)
#[arg(short, long)]
device: Option<String>,
/// User ID (defaults to 0)
#[arg(short, long)]
user: Option<u16>,
},
}
#[tokio::main]
async fn main() -> ExitCode {
match run() {
Ok(()) => ExitCode::SUCCESS,
Err(err) => {
eprintln!("Error: {err}");
ExitCode::FAILURE
}
}
}
fn run() -> Result<(), Box<dyn std::error::Error>> {
let cli = Cli::parse();
match cli.command {
Commands::Devices => {
commands::list_devices()?;
}
Commands::List {
device,
state,
removal,
list,
search,
user,
} => {
commands::list_packages(device, state, removal, list, search, user)?;
}
Commands::Uninstall {
packages,
device,
user,
dry_run,
} => {
commands::change_package_state(
&packages,
device,
user,
dry_run,
PackageState::Uninstalled,
"Uninstalling",
)?;
}
Commands::Enable {
packages,
device,
user,
dry_run,
} => {
commands::change_package_state(
&packages,
device,
user,
dry_run,
PackageState::Enabled,
"Enabling",
)?;
}
Commands::Disable {
packages,
device,
user,
dry_run,
} => {
commands::change_package_state(
&packages,
device,
user,
dry_run,
PackageState::Disabled,
"Disabling",
)?;
}
Commands::Info {
package,
device,
user,
} => {
commands::show_package_info(&package, device, user)?;
}
Commands::Update => {
commands::update_lists()?;
}
Commands::Completions { shell } => {
commands::generate_completions(shell);
}
Commands::Repl { device, user } => {
repl::repl_mode(device, user)?;
}
}
Ok(())
}

View file

@ -0,0 +1,18 @@
/// Helper macro to handle broken pipe errors gracefully
/// When piping to commands like `head`, we want to exit cleanly when the pipe closes
#[macro_export]
macro_rules! println_or_exit {
() => {
let _ = writeln!(std::io::stdout());
};
($($arg:tt)*) => {
let _ = writeln!(std::io::stdout(), $($arg)*);
};
}
#[macro_export]
macro_rules! print_or_exit {
($($arg:tt)*) => {
let _ = write!(std::io::stdout(), $($arg)*);
};
}

374
crates/uad-cli/src/repl.rs Normal file
View file

@ -0,0 +1,374 @@
use rustyline::DefaultEditor;
use rustyline::error::ReadlineError;
use std::collections::HashMap;
use std::io::Write;
use uad_core::adb::ACommand;
use uad_core::sync::{CorePackage, Phone, User, apply_pkg_state_commands, get_package_state};
use uad_core::uad_lists::{Package, PackageState, Removal, UadList, load_debloat_lists};
use crate::commands::{PackageListContext, display_package_list, execute_with_fallback};
use crate::device::{get_target_device, get_user};
use crate::filters::StateFilter;
use crate::println_or_exit;
enum ReplAction {
Continue,
Exit,
}
/// Start interactive REPL mode
pub fn repl_mode(
device: Option<String>,
user_id: Option<u16>,
) -> Result<(), Box<dyn std::error::Error>> {
println!("Universal Android Debloater - Interactive Mode");
println!("Type 'help' for available commands, 'exit' or 'quit' to leave\n");
let target_device = get_target_device(device)?;
let user = get_user(&target_device, user_id)?;
println!(
"Connected to: {} ({})",
target_device.model, target_device.adb_id
);
println!("User: {}\n", user.id);
let uad_lists = load_debloat_lists(false).unwrap_or_else(|lists| lists);
let mut rl = DefaultEditor::new()?;
// Try to load history
let history_file = dirs::cache_dir().map(|d| d.join("uad").join("cli_history.txt"));
if let Some(ref path) = history_file {
let _ = rl.load_history(path);
}
loop {
let readline = rl.readline("uad> ");
match readline {
Ok(line) => {
match handle_repl_line(&line, &mut rl, &target_device, user, user_id, &uad_lists) {
Ok(ReplAction::Continue) => {}
Ok(ReplAction::Exit) => break,
Err(e) => {
eprintln!("Error: {}", e);
}
}
}
Err(ReadlineError::Interrupted) => {
println!("Interrupted (Ctrl-C). Type 'exit' to quit.");
continue;
}
Err(ReadlineError::Eof) => {
println!("Goodbye!");
break;
}
Err(err) => {
eprintln!("Error: {:?}", err);
break;
}
}
}
// Save history
if let Some(ref path) = history_file {
if let Some(parent) = path.parent() {
let _ = std::fs::create_dir_all(parent);
}
let _ = rl.save_history(path);
}
Ok(())
}
/// Handle a single line of REPL input
fn handle_repl_line(
line: &str,
rl: &mut DefaultEditor,
device: &Phone,
user: User,
user_id: Option<u16>,
uad_lists: &HashMap<String, Package>,
) -> Result<ReplAction, Box<dyn std::error::Error>> {
let line = line.trim();
if line.is_empty() {
return Ok(ReplAction::Continue);
}
let _ = rl.add_history_entry(line);
let parts: Vec<&str> = line.split_whitespace().collect();
if parts.is_empty() {
return Ok(ReplAction::Continue);
}
match parts[0] {
"help" => print_repl_help(),
"exit" | "quit" => {
println!("Goodbye!");
return Ok(ReplAction::Exit);
}
"list" | "ls" => {
handle_list_command(&parts[1..], device, user_id, uad_lists)?;
}
"info" => {
handle_info_command(&parts[1..], device, user.id, uad_lists)?;
}
"uninstall" | "rm" => {
handle_state_change_command(
&parts[1..],
device,
user,
PackageState::Uninstalled,
"Uninstalling",
uad_lists,
)?;
}
"enable" | "restore" => {
handle_state_change_command(
&parts[1..],
device,
user,
PackageState::Enabled,
"Enabling",
uad_lists,
)?;
}
"disable" => {
handle_state_change_command(
&parts[1..],
device,
user,
PackageState::Disabled,
"Disabling",
uad_lists,
)?;
}
"device" => {
println!(
"Device: {} ({}), Android SDK: {}, User: {}",
device.model, device.adb_id, device.android_sdk, user.id
);
}
"clear" => {
print!("\x1B[2J\x1B[1;1H");
}
_ => {
eprintln!(
"Unknown command: '{}'. Type 'help' for available commands.",
parts[0]
);
}
}
Ok(ReplAction::Continue)
}
/// Parse REPL arguments into filters
struct ReplListArgs {
state_filter: Option<StateFilter>,
search_term: Option<String>,
}
impl ReplListArgs {
fn parse(args: &[&str]) -> Result<Self, String> {
let mut state_filter = None;
let mut search_term = None;
let mut i = 0;
while i < args.len() {
match args[i] {
"--state" | "-s" => {
if i + 1 >= args.len() {
return Err("--state requires a value".to_string());
}
state_filter = match args[i + 1].to_lowercase().as_str() {
"enabled" => Some(StateFilter::Enabled),
"disabled" => Some(StateFilter::Disabled),
"uninstalled" => Some(StateFilter::Uninstalled),
"all" => Some(StateFilter::All),
_ => return Err(format!("Invalid state: {}", args[i + 1])),
};
i += 2;
}
"--search" | "-q" => {
if i + 1 >= args.len() {
return Err("--search requires a value".to_string());
}
search_term = Some(args[i + 1].to_string());
i += 2;
}
_ => {
return Err(format!("Unknown option: {}", args[i]));
}
}
}
Ok(Self {
state_filter,
search_term,
})
}
}
/// Handle list command in REPL
fn handle_list_command(
args: &[&str],
device: &Phone,
user_id: Option<u16>,
uad_lists: &HashMap<String, Package>,
) -> Result<(), Box<dyn std::error::Error>> {
let parsed = ReplListArgs::parse(args)?;
let pm_flag = parsed.state_filter.and_then(StateFilter::to_pm_flag);
let system_packages = ACommand::new()
.shell(&device.adb_id)
.pm()
.list_packages_sys(pm_flag, user_id)?;
let context = PackageListContext {
state_filter: parsed.state_filter,
removal_filter: None,
list_filter: None,
search: parsed.search_term,
};
let displayed_count = display_package_list(
&system_packages,
uad_lists,
&device.adb_id,
user_id,
&context,
)?;
if displayed_count == 0 {
println_or_exit!(" No packages found.");
} else {
println_or_exit!("\nTotal: {} package(s)", displayed_count);
}
Ok(())
}
/// Handle info command in REPL
fn handle_info_command(
args: &[&str],
device: &Phone,
user_id: u16,
uad_lists: &HashMap<String, Package>,
) -> Result<(), Box<dyn std::error::Error>> {
if args.is_empty() {
eprintln!("Usage: info <package_name>");
return Ok(());
}
let package = args[0];
println!("Package: {}", package);
if let Some(pkg_info) = uad_lists.get(package) {
println!(" List: {}", pkg_info.list);
println!(" Removal: {}", pkg_info.removal);
println!(" Description: {}", pkg_info.description);
} else {
println!(" Not found in UAD lists (unlisted package)");
}
let state = get_package_state(&device.adb_id, package, Some(user_id))
.ok_or("Package not found on device")?;
println!(" State: {}", state);
Ok(())
}
/// Handle state change command in REPL
fn handle_state_change_command(
args: &[&str],
device: &Phone,
user: User,
target_state: PackageState,
action_name: &str,
uad_lists: &HashMap<String, Package>,
) -> Result<(), Box<dyn std::error::Error>> {
if args.is_empty() {
eprintln!(
"Usage: {} <package_name> [package_name...]",
action_name.to_lowercase()
);
return Ok(());
}
for pkg_name in args {
process_package_change(pkg_name, device, user, target_state, action_name, uad_lists)?;
}
Ok(())
}
/// Process state change for a single package in REPL
fn process_package_change(
pkg_name: &str,
device: &Phone,
user: User,
target_state: PackageState,
action_name: &str,
uad_lists: &HashMap<String, Package>,
) -> Result<(), Box<dyn std::error::Error>> {
let current_state = get_package_state(&device.adb_id, pkg_name, Some(user.id))
.ok_or("Package not found on device")?;
println!("{} {} (current: {})", action_name, pkg_name, current_state);
if current_state == target_state {
println!(" → Already in target state, skipping");
return Ok(());
}
let pkg_info = uad_lists.get(pkg_name);
if let Some(info) = pkg_info {
if info.removal == Removal::Unsafe {
println!(" ⚠ WARNING: This package is marked as UNSAFE to remove!");
}
}
let core_pkg = CorePackage {
name: pkg_name.to_string(),
description: pkg_info.map(|p| p.description.clone()).unwrap_or_default(),
removal: pkg_info.map(|p| p.removal).unwrap_or(Removal::Unlisted),
state: current_state,
list: pkg_info.map(|p| p.list).unwrap_or(UadList::Unlisted),
};
let commands = apply_pkg_state_commands(&core_pkg, target_state, user, device);
execute_with_fallback(
pkg_name,
target_state,
&core_pkg,
user,
device,
&commands,
" ",
)
}
/// Print REPL help message
fn print_repl_help() {
println!("Available commands:");
println!(" list [--state <state>] [--search <term>]");
println!(" List packages with optional filters");
println!(" info <package_name>");
println!(" Show information about a package");
println!(" uninstall <package_name> [package_name...]");
println!(" Uninstall one or more packages");
println!(" enable <package_name> [package_name...]");
println!(" Enable/restore one or more packages");
println!(" disable <package_name> [package_name...]");
println!(" Disable one or more packages");
println!(" device");
println!(" Show current device information");
println!(" clear");
println!(" Clear the screen");
println!(" help");
println!(" Show this help message");
println!(" exit, quit");
println!(" Exit the interactive mode");
}

View file

@ -0,0 +1,52 @@
[package]
name = "uad-core"
version.workspace = true
authors.workspace = true
license.workspace = true
homepage.workspace = true
repository.workspace = true
readme.workspace = true
keywords.workspace = true
categories = ["command-line-utilities"]
edition.workspace = true
[features]
default = []
self-update = ["dep:flate2", "dep:tar"]
[dependencies]
serde.workspace = true
serde_json.workspace = true
log.workspace = true
chrono.workspace = true
toml.workspace = true
dirs.workspace = true
ureq.workspace = true
retry.workspace = true
csv.workspace = true
flate2 = { workspace = true, optional = true }
tar = { workspace = true, optional = true }
[target.'cfg(target_os = "windows")'.dependencies]
win32console.workspace = true
[lints.rust]
deprecated_safe = "warn"
[lints.clippy]
undocumented_unsafe_blocks = "forbid"
exit = "deny"
panic_in_result_fn = "warn"
infinite_loop = "warn"
mem_forget = "warn"
implicit_clone = "warn"
format_push_string = "warn"
large_include_file = "warn"
shadow_unrelated = "warn"
struct_field_names = "allow" # annoying
disallowed_types = "deny"
disallowed_methods = "deny"
allow_attributes_without_reason = "warn"
pedantic = { level = "warn", priority = -1 }

503
crates/uad-core/src/adb.rs Normal file
View file

@ -0,0 +1,503 @@
#![deny(clippy::unwrap_used)]
//! This module is intended to group everything that's "intrinsic" of ADB.
//!
//! Following the design philosophy of most of Rust `std`,
//! `*Command` are intended to be "thin wrappers" (low-overhead abstractions)
//! around the ADB CLI or `adb_client`
//! ([in the future](https://github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation/issues/700) ),
//! which implies:
//! - no "magic"
//! - no custom commands
//! - no chaining ("piping") of existing commands
//!
//! This guarantees a 1-to-1 mapping between methods and cmds,
//! thereby reducing surprises such as:
//! - Non-atomic operations: consider what happens if a pack changes state
//! in the middle of listing enabled and disabled packs!
//! - Non-standard semantics: what would happen if a new ADB version
//! supports a feature we already defined,
//! but has _slightly_ different behavior?
//!
//! Despite being "low-level", we can still "have cake and eat it too";
//! After all, what's the point of an abstraction if it doesn't come with goodies?:
//! We can reserve some artistic license, such as:
//! - pre-parsing or validanting output, to provide types with invariants
//! - strongly-typed rather than "stringly-typed" APIs
//! - nicer IDE support
//! - compile-time prevention of malformed cmds
//! - implicit enforcement of a narrow set of operations
//!
//! About that last point, if there's ever a need for an ADB feature
//! which these APIs don't expose,
//! please, **PLEASE** refrain from falling-back to any `Command`-like API.
//! Rather, please extend these APIs in a consistent way.
//!
//! Thank you! ❤️
//!
//! For comprehensive info about ADB,
//! [see this](https://android.googlesource.com/platform/packages/modules/adb/+/refs/heads/master/docs/)
use std::rc::Rc;
#[cfg(target_os = "windows")]
use std::os::windows::process::CommandExt;
use crate::utils::is_all_w_c;
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.
#[must_use]
pub fn to_trimmed_utf8(v: &[u8]) -> String {
String::from_utf8_lossy(v).trim_end().to_string()
}
#[cfg(debug_assertions)]
#[must_use]
fn is_version_triple(s: &str) -> bool {
let mut components = s.split('.');
for _ in 0..3 {
if !components
.next()
.is_some_and(|comp| comp.as_bytes().iter().all(u8::is_ascii_digit))
{
return false;
}
}
if components.next().is_some() {
return false;
}
true
}
/// Builder object for an Android Debug Bridge CLI command,
/// using the type-state and new-type patterns.
///
/// This is not intended to model the entire ADB API.
/// It only models the subset that concerns UADNG.
///
/// [More info here](https://developer.android.com/tools/adb)
#[derive(Debug)]
pub struct ACommand(std::process::Command);
impl ACommand {
/// `adb` command builder
#[must_use]
pub fn new() -> Self {
Self(std::process::Command::new("adb"))
}
/// `shell` sub-command builder.
///
/// If `device_serial` is empty, it lets ADB choose the default device.
#[must_use]
pub fn shell<S: AsRef<str>>(mut self, device_serial: S) -> ShellCommand {
let serial = device_serial.as_ref();
if !serial.is_empty() {
self.0.args(["-s", serial]);
}
self.0.arg("shell");
ShellCommand(self)
}
/// Header-less list of attached devices (as serials) and their statuses:
/// - USB
/// - TCP/IP: WIFI, Ethernet, etc...
/// - Local emulators
///
/// Status can be (but not limited to):
/// - "unauthorized"
/// - "device"
pub fn devices(mut self) -> Result<Vec<(String, String)>, String> {
self.0.arg("devices");
Ok(self
.run()?
.lines()
.skip(1) // header
.map(|dev_stat| {
let tab_idx = dev_stat
// OS-specific?
.find('\t')
// True on Linux,
// no matter if ADB is piped or connected to terminal
.expect("There must be 1 tab after serial");
(
// serial
dev_stat[..tab_idx].to_string(),
// status
dev_stat[(tab_idx + 1)..].to_string(),
)
})
.collect())
}
/// `version` sub-command
///
/// ## Format
/// This is just a sample,
/// we don't know which guarantees are stable (yet):
/// ```txt
/// Android Debug Bridge version 1.0.41
/// Version 34.0.5-debian
/// Installed as /usr/lib/android-sdk/platform-tools/adb
/// Running on Linux 6.12.12-amd64 (x86_64)
/// ```
///
/// The expected format should be like:
/// ```txt
/// Android Debug Bridge version <num>.<num>.<num>
/// Version <num>.<num>.<num>-<no spaces>
/// Installed as <ANDROID_SDK_HOME>/platform-tools/adb[.exe]
/// Running on <OS/kernel version> (<CPU arch>)
/// ```
#[expect(clippy::panic_in_result_fn, reason = "Assertions are fine")]
pub fn version(mut self) -> Result<String, String> {
self.0.arg("version");
let out = self.run()?;
#[cfg(debug_assertions)]
{
const ADBV: &str = "Android Debug Bridge version ";
const V: &str = "Version ";
let mut lns = out.lines();
assert!(
lns.next()
.is_some_and(|ln| ln.starts_with(ADBV) && is_version_triple(&ln[ADBV.len()..]))
);
assert!(lns.next().is_some_and(|ln| ln.starts_with(V)
&& is_version_triple(&ln[V.len()..ln.find('-').unwrap_or(ln.len())])));
// missing test for valid path
assert!(lns.next().is_some_and(|ln| ln.starts_with("Installed as ")
&& (ln.ends_with("adb") || ln.ends_with("adb.exe"))));
// missing test for x86/ARM (both 64b)
assert!(lns.next().is_some_and(|ln| ln.starts_with("Running on ")));
if lns.next().is_some() {
unreachable!("Expected < 5 lines")
}
}
Ok(out)
}
/// General executor
fn run(self) -> Result<String, String> {
let mut cmd = self.0;
#[cfg(target_os = "windows")]
let cmd = cmd.creation_flags(0x0800_0000); // do not open a cmd window
info!(
"Ran command: adb {}",
cmd.get_args()
.map(|s| s.to_str().unwrap_or_else(|| unreachable!()))
.collect::<Vec<_>>()
.join(" ")
);
match cmd.output() {
Err(e) => {
error!("ADB: {e}");
Err("Cannot run ADB, likely not found".to_string())
}
Ok(o) => {
let stdout = to_trimmed_utf8(&o.stdout);
if o.status.success() {
Ok(stdout)
} else {
let stderr = to_trimmed_utf8(&o.stderr);
// ADB does really weird things:
// Some errors are not redirected to `stderr`
let err = if stdout.is_empty() { stderr } else { stdout };
Err(err)
}
}
}
}
}
impl Default for ACommand {
fn default() -> Self {
Self::new()
}
}
/// Builder object for a command that runs 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).
#[derive(Debug)]
pub struct ShellCommand(ACommand);
impl ShellCommand {
/// `pm` command builder
pub fn pm(mut self) -> PmCommand {
self.0.0.arg("pm");
PmCommand(self)
}
/// Query a device property value, by its key.
/// These can be of any type:
/// - `boolean`
/// - `int`
/// - chars
/// - etc...
///
/// So to avoid lossy conversions, we return strs
pub fn getprop(mut self, key: &str) -> Result<String, String> {
self.0.0.args(["getprop", key]);
self.0.run()
}
/// Reboots device
pub fn reboot(mut self) -> Result<String, String> {
self.0.0.arg("reboot");
self.0.run()
}
/// Execute an arbitrary shell action string on the device's default shell.
/// The action string is passed as a single argument to `adb shell` and
/// interpreted by the remote shell (which splits on spaces).
pub fn raw(mut self, action: &str) -> Result<String, String> {
self.0.0.arg(action);
self.0.run()
}
}
#[must_use]
pub const fn is_pkg_component(s: &[u8]) -> bool {
if s.is_empty() {
return false;
}
s[0].is_ascii_alphabetic()
&& if s.len() > 1 {
is_all_w_c(s.split_at(1).1)
} else {
true
}
}
/// String with the invariant of being a valid package-name.
/// See [`PackageId::new`] for validation details.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct PackageId(Rc<str>);
impl PackageId {
/// Creates a package-ID if it's `"android"` or valid according to:
/// - <https://developer.android.com/guide/topics/manifest/manifest-element.html#package>
/// - <https://developer.android.com/build/configure-app-module#set-application-id>
#[must_use]
pub fn new(p_id: &str) -> Option<Self> {
if p_id == "android" {
return Some(Self(p_id.into()));
}
let mut components = p_id.split('.');
for _ in 0..2 {
if !components
.next()
.is_some_and(|comp| is_pkg_component(comp.as_bytes()))
{
return None;
}
}
if components.all(|comp| is_pkg_component(comp.as_bytes())) {
Some(Self(p_id.into()))
} else {
None
}
}
}
/// `pm list packages` flag/state/type
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum PmListPacksFlag {
/// `-u`, not to be confused with `-a`
IncludeUninstalled,
/// `-e`
OnlyEnabled,
/// `-d`
OnlyDisabled,
}
impl PmListPacksFlag {
// is there a trait for this?
fn to_str(self) -> &'static str {
match self {
Self::IncludeUninstalled => "-u",
Self::OnlyEnabled => "-e",
Self::OnlyDisabled => "-d",
}
}
}
#[expect(clippy::to_string_trait_impl, reason = "This is not user-facing")]
impl ToString for PmListPacksFlag {
fn to_string(&self) -> String {
self.to_str().to_string()
}
}
const PACK_PREFIX: &str = "package:";
pub const PM_CLEAR_PACK: &str = "pm clear";
/// Builder object for an Android Package Manager command.
/// <https://developer.android.com/tools/adb#pm>
#[derive(Debug)]
#[must_use]
pub struct PmCommand(ShellCommand);
impl PmCommand {
/// `list packages -s` sub-command, [`PACK_PREFIX`] stripped from each element.
///
/// `Ok` variant:
/// - isn't 100% guaranteed to contain valid pack-IDs
/// but you can assume it does (except in `unsafe {}` blocks)
/// - isn't sorted
/// - duplicates never _seem_ to happen, but don't assume uniqueness
pub fn list_packages_sys(
mut self,
f: Option<PmListPacksFlag>,
user_id: Option<u16>,
) -> Result<Vec<String>, String> {
let cmd = &mut self.0.0.0;
cmd.args(["list", "packages", "-s"]);
if let Some(s) = f {
cmd.arg(s.to_str());
}
if let Some(u) = user_id {
cmd.arg("--user");
cmd.arg(u.to_string());
}
self.0.0.run().map(|pack_ls| {
pack_ls
.lines()
.filter_map(|p_ln| {
debug_assert!(p_ln.starts_with(PACK_PREFIX));
let p = &p_ln[PACK_PREFIX.len()..];
if PackageId::new(p).is_some() {
Some(String::from(p))
} else {
warn!("skipping nonstandard package name: {p:?}");
None
}
})
.collect()
})
}
/// `list users` sub-command, deserialized/parsed.
///
/// - <https://source.android.com/docs/devices/admin/multi-user-testing>
/// - <https://stackoverflow.com/questions/37495126/android-get-list-of-users-and-profile-name>
pub fn list_users(mut self) -> Result<Box<[UserInfo]>, String> {
self.0.0.0.args(["list", "users"]);
Ok(self
.0
.0
.run()?
.lines()
.skip(1) // omit header
.map(|ln| {
// this could be optimized by making more API-stability assumptions
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 ln = if let Some(l) = ln.strip_suffix("running") {
//run = true;
l.trim_ascii_end()
} else {
//run = false;
ln
};
let ln = ln.strip_suffix('}').unwrap_or(ln).trim_ascii_end();
// https://android.googlesource.com/platform/frameworks/base/+/refs/heads/main/core/java/android/content/pm/UserInfo.java
// The format looks stable today, but google may change it in future Android versions
// (and very old Androids might differ). Keep parsing defensive.
// Expected shape: "UserInfo{<id>:<name>:<flags>}[ running]"
let mut comps = ln.split(':');
let id = comps
.next()
.expect("There must be at least 1 ':'-separated component")
.parse()
.expect("string assumed to be UID numeral");
//let name = comps
// .next()
// .expect("There must be at least 2 ':'-separated components. 2nd is user-name");
//let flags = u32::from_str_radix(
// comps.next().expect(
// "There must be at least 3 ':'-separated components. 3rd is user bit-flags",
// ),
// 16,
//)
//.expect("string assumed to be hexadecimal bit-flags");
UserInfo {
id,
//name: name.into(),
//flags,
//running: run,
}
})
.collect())
}
}
/// Mirror of AOSP `UserInfo` Java Class, with an extra field
#[derive(Debug, Clone)]
pub struct UserInfo {
id: u16,
//name: Box<str>,
//flags: u32,
//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]
#[allow(dead_code, reason = "Currently unused by UI; kept for future features")]
pub const fn was_running(&self) -> bool {
self.running
}
*/
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn invalid_pack_ids() {
for p_id in [
"",
" ",
".",
"nodots",
"com..example",
"net.hello.",
"org.0example",
"org._foobar",
"the.🎂.is.a.lie",
"EXCLAMATION!!!!",
] {
assert_eq!(PackageId::new(p_id), None);
}
}
#[test]
fn valid_pack_ids() {
for p_id in [
"A.a",
"x.X",
"org.example",
"net.hello",
"uwu.owo",
"Am0Gu5.Zuz",
"net.net.net.net.net.net.net.net.net.net.net",
"com.github.w1nst0n",
"this_.String_.is_.not_.real_",
] {
assert_ne!(PackageId::new(p_id), None);
}
}
}

View file

@ -0,0 +1,150 @@
use crate::CACHE_DIR;
use crate::CONFIG_DIR;
use crate::sync::User;
use crate::utils::DisplayablePath;
use log::error;
use serde::{Deserialize, Serialize};
use std::fs;
use std::path::PathBuf;
use std::sync::LazyLock;
const DEFAULT_THEME: &str = "Auto (follow system theme)";
#[derive(Default, Debug, Serialize, Deserialize, Clone)]
pub struct Config {
pub general: GeneralSettings,
#[serde(skip_serializing_if = "Vec::is_empty", default = "Vec::new")]
pub devices: Vec<DeviceSettings>,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct GeneralSettings {
pub theme: String,
pub expert_mode: bool,
pub backup_folder: PathBuf,
}
#[derive(Default, Debug, Clone)]
pub struct BackupSettings {
pub backups: Vec<DisplayablePath>,
pub selected: Option<DisplayablePath>,
pub users: Vec<User>,
pub selected_user: Option<User>,
pub backup_state: String,
}
#[derive(Debug, Serialize, Deserialize, Clone, Default)]
pub struct DeviceSettings {
/// Unique serial identifier
pub device_id: String,
pub disable_mode: bool, // should be `enum RemovalMode`
pub multi_user_mode: bool,
#[serde(skip)]
pub backup: BackupSettings,
}
impl Default for GeneralSettings {
fn default() -> Self {
Self {
theme: DEFAULT_THEME.to_string(),
expert_mode: false,
backup_folder: CACHE_DIR.join("backups"),
}
}
}
static CONFIG_FILE: LazyLock<PathBuf> = LazyLock::new(|| CONFIG_DIR.join("config.toml"));
impl Config {
pub fn save_device_settings(
&mut self,
device_settings: DeviceSettings,
general: GeneralSettings,
) {
if let Some(device) = self
.devices
.iter_mut()
.find(|x| x.device_id == device_settings.device_id)
{
*device = device_settings;
} else {
self.devices.push(device_settings);
}
self.general = general;
let toml = toml::to_string(&self).unwrap();
fs::write(&*CONFIG_FILE, toml).expect("Could not write config file to disk!");
}
#[must_use]
pub fn load_configuration_file() -> Self {
match fs::read_to_string(&*CONFIG_FILE) {
Ok(s) => match toml::from_str(&s) {
Ok(config) => return config,
Err(e) => error!("Invalid config file: `{e}`"),
},
Err(e) => error!("Failed to read config file: `{e}`"),
}
error!("Restoring default config file");
let toml = toml::to_string(&Self::default()).unwrap();
fs::write(&*CONFIG_FILE, toml).expect("Could not write config file to disk!");
Self::default()
}
}
#[cfg(test)]
mod tests {
//! Unit tests
use super::*;
use std::path::Path;
// create a clean default config file for testing
fn create_default_config_file() {
let toml = toml::to_string(&Config::default()).unwrap();
fs::write(&*CONFIG_FILE, toml).expect("Could not write config file to disk!");
}
#[test]
fn test_create_default_config_file() {
create_default_config_file();
assert!(CONFIG_FILE.exists());
}
#[test]
fn test_load_configuration_file() {
create_default_config_file();
let config = Config::load_configuration_file();
// non-deterministic
//assert_eq!(config.devices.len(), 0);
assert_eq!(config.general.theme, DEFAULT_THEME);
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();
let device_id = "test_device".to_string();
settings.device.device_id = device_id.clone();
Config::save_changes(&settings, &device_id);
let config = Config::load_configuration_file();
assert_eq!(config.devices[0].device_id, device_id);
}
*/
#[test]
fn test_default_config() {
let config = Config::default();
assert_eq!(config.devices.len(), 0);
assert_eq!(config.general.theme, DEFAULT_THEME);
assert!(!config.general.expert_mode);
assert_eq!(config.general.backup_folder, CACHE_DIR.join("backups"));
}
#[test]
fn test_config_file_path() {
assert_eq!(&*CONFIG_FILE, Path::new(&*CONFIG_DIR.join("config.toml")));
}
}

View file

@ -0,0 +1,23 @@
#![allow(
clippy::missing_panics_doc,
clippy::missing_errors_doc,
clippy::collapsible_if,
clippy::uninlined_format_args,
clippy::result_unit_err,
reason = "Doc+style pedantic lints are out-of-scope for this pass"
)]
pub mod adb;
pub mod config;
pub mod save;
pub mod sync;
pub mod uad_lists;
pub mod update;
pub mod utils;
use std::path::PathBuf;
use std::sync::LazyLock;
pub static CONFIG_DIR: LazyLock<PathBuf> =
LazyLock::new(|| utils::setup_uad_dir(&dirs::config_dir().expect("Can't detect config dir")));
pub static CACHE_DIR: LazyLock<PathBuf> =
LazyLock::new(|| utils::setup_uad_dir(&dirs::cache_dir().expect("Can't detect cache dir")));

View file

@ -1,34 +1,31 @@
use crate::core::config::DeviceSettings;
use crate::core::sync::{apply_pkg_state_commands, CorePackage, Phone, User};
use crate::core::utils::DisplayablePath;
use crate::gui::widgets::package_row::PackageRow;
use crate::CACHE_DIR;
use crate::config::{Config, DeviceSettings};
use crate::sync::{CorePackage, Phone, User, apply_pkg_state_commands};
use crate::utils::DisplayablePath;
use log::{error, info, warn};
use serde::{Deserialize, Serialize};
use static_init::dynamic;
use std::fs;
use std::path::{Path, PathBuf};
#[dynamic]
pub static BACKUP_DIR: PathBuf = CACHE_DIR.join("backups");
use std::{
fs,
path::{Path, PathBuf},
};
#[derive(Default, Deserialize, Serialize, Debug, Clone, PartialEq, Eq)]
struct PhoneBackup {
device_id: String,
users: Vec<UserBackup>,
pub struct PhoneBackup {
pub device_id: String,
pub users: Vec<UserBackup>,
}
#[derive(Default, Deserialize, Serialize, Debug, Clone, PartialEq, Eq)]
struct UserBackup {
id: u16,
packages: Vec<CorePackage>,
pub struct UserBackup {
pub id: u16,
pub packages: Vec<CorePackage>,
}
// Backup all `Uninstalled` and `Disabled` packages
pub async fn backup_phone(
/// Backup all `Uninstalled` and `Disabled` packages
pub fn backup_phone(
users: Vec<User>,
device_id: String,
phone_packages: Vec<Vec<PackageRow>>,
) -> Result<(), String> {
phone_packages: &[Vec<CorePackage>],
) -> Result<bool, String> {
let mut backup = PhoneBackup {
device_id: device_id.clone(),
..PhoneBackup::default()
@ -40,29 +37,27 @@ pub async fn backup_phone(
..UserBackup::default()
};
for p in phone_packages[u.index].clone() {
user_backup.packages.push(CorePackage {
name: p.name.clone(),
state: p.state,
});
for p in phone_packages[u.index].iter().cloned() {
user_backup.packages.push(p);
}
backup.users.push(user_backup);
}
match serde_json::to_string_pretty(&backup) {
Ok(json) => {
let backup_path = &*BACKUP_DIR.join(device_id);
let backup_dir: PathBuf = Config::load_configuration_file().general.backup_folder;
let backup_path = &*backup_dir.join(device_id);
if let Err(e) = fs::create_dir_all(backup_path) {
error!("BACKUP: could not create backup dir: {}", e);
error!("BACKUP: could not create backup dir: {e}");
return Err(e.to_string());
};
}
let backup_filename =
format!("{}.json", chrono::Local::now().format("%Y-%m-%d_%H-%M-%S"));
match fs::write(backup_path.join(backup_filename), json) {
Ok(_) => Ok(()),
Ok(()) => Ok(true),
Err(err) => Err(err.to_string()),
}
}
@ -71,34 +66,30 @@ pub async fn backup_phone(
}
pub fn list_available_backups(dir: &Path) -> Vec<DisplayablePath> {
#[allow(clippy::option_if_let_else)]
match fs::read_dir(dir) {
Ok(files) => files
.filter_map(|e| e.ok())
.filter_map(Result::ok)
.map(|e| DisplayablePath { path: e.path() })
.collect::<Vec<_>>(),
Err(_) => vec![],
}
}
#[must_use]
pub fn list_available_backup_user(backup: DisplayablePath) -> Vec<User> {
match fs::read_to_string(backup.path) {
Ok(data) => {
let phone_backup: PhoneBackup =
serde_json::from_str(&data).expect("Unable to parse backup file");
let mut users = vec![];
for u in phone_backup.users {
users.push(User {
id: u.id,
index: 0,
protected: false,
});
}
users
}
Ok(data) => serde_json::from_str::<PhoneBackup>(&data)
.expect("Unable to parse backup file")
.users
.into_iter()
.map(|u| User {
id: u.id,
index: 0,
protected: false,
})
.collect(),
Err(e) => {
error!("[BACKUP]: Selected backup file not found: {}", e);
error!("[BACKUP]: Selected backup file not found: {e}");
vec![]
}
}
@ -106,15 +97,22 @@ pub fn list_available_backup_user(backup: DisplayablePath) -> Vec<User> {
#[derive(Debug)]
pub struct BackupPackage {
pub i_user: usize,
pub index: usize,
pub commands: Vec<String>,
}
#[derive(Debug)]
pub struct RestoreResult {
pub packages: Vec<BackupPackage>,
pub skipped_count: usize,
}
pub fn restore_backup(
selected_device: &Phone,
packages: &[Vec<PackageRow>],
packages: &[Vec<CorePackage>],
settings: &DeviceSettings,
) -> Result<Vec<BackupPackage>, String> {
) -> Result<RestoreResult, String> {
match fs::read_to_string(
settings
.backup
@ -129,30 +127,31 @@ pub fn restore_backup(
serde_json::from_str(&data).expect("Unable to parse backup file");
let mut commands = vec![];
let mut skipped_packages = 0;
for u in phone_backup.users {
let index = match selected_device.user_list.iter().find(|x| x.id == u.id) {
let i_user = match selected_device.user_list.iter().find(|x| x.id == u.id) {
Some(i) => i.index,
None => return Err(format!("user {} doesn't exist", u.id)),
};
for (i, backup_package) in u.packages.iter().enumerate() {
let package: CorePackage;
match packages[index]
let package: CorePackage = if let Some(p) = packages[i_user]
.iter()
.find(|x| x.name == backup_package.name)
{
Some(p) => package = p.into(),
None => {
return Err(format!(
"{} not found for user {}",
backup_package.name, u.id
))
}
}
p.clone()
} else {
skipped_packages += 1;
warn!(
"{} not found for user {} - skipping package during restore",
backup_package.name, u.id
);
continue;
};
let p_commands = apply_pkg_state_commands(
&package,
backup_package.state,
&settings
settings
.backup
.selected_user
.ok_or("field should be Some type")?,
@ -160,19 +159,29 @@ pub fn restore_backup(
);
if !p_commands.is_empty() {
commands.push(BackupPackage {
i_user,
index: i,
commands: p_commands,
});
}
}
}
if skipped_packages > 0 {
info!(
"Restore completed with {skipped_packages} packages skipped (not found on device)"
);
}
if !commands.is_empty() {
commands.push(BackupPackage {
i_user: 0,
index: 0,
commands: vec![],
});
}
Ok(commands)
Ok(RestoreResult {
packages: commands,
skipped_count: skipped_packages,
})
}
Err(e) => Err(e.to_string()),
}

663
crates/uad-core/src/sync.rs Normal file
View file

@ -0,0 +1,663 @@
use crate::{
adb::{ACommand as AdbCommand, PM_CLEAR_PACK, PackageId},
uad_lists::PackageState,
};
use log::{error, info};
use retry::{OperationResult, delay::Fixed, retry};
use serde::{Deserialize, Serialize};
/// An Android device, typically a phone
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Phone {
/// Non-market name
pub model: String, // could be `Copy`
/// Android API level version
pub android_sdk: u8,
/// In theory, `len < u16::MAX` _should_ always be `true`.
/// In practice, `len <= u8::MAX`.
pub user_list: Vec<User>,
/// Unique serial identifier
pub adb_id: String, // could be `Copy`
}
impl Default for Phone {
fn default() -> Self {
Self {
model: "fetching devices...".to_string(),
android_sdk: 0,
user_list: vec![],
adb_id: String::default(),
}
}
}
impl std::fmt::Display for Phone {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.model)
}
}
/// `UserInfo` but relevant to UAD
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)]
pub struct User {
pub id: u16,
pub index: usize,
pub protected: bool,
}
impl std::fmt::Display for User {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "user {}", self.id)
}
}
/// An enum to contain different variants for errors yielded by ADB.
#[derive(Debug, Clone)]
pub enum AdbError {
Generic(String),
}
/// Run an arbitrary shell action via the typed ADB wrapper.
/// This replaces the deprecated `adb_shell_command`.
///
/// If `serial` is empty, it lets ADB choose the default device.
pub fn run_adb_shell_action<S: AsRef<str>>(
device_serial: S,
action: &str,
) -> Result<String, AdbError> {
let serial = device_serial.as_ref();
match AdbCommand::new().shell(serial).raw(action) {
Ok(o) => {
if ["Error", "Failure"].iter().any(|&e| o.contains(e)) {
let friendly_msg = make_friendly_error_message(&o, action);
return Err(AdbError::Generic(friendly_msg));
}
info!("{action} -> {o}");
Ok(o)
}
Err(err) => {
if !err.contains("[not installed for") {
let friendly_msg = make_friendly_error_message(&err, action);
return Err(AdbError::Generic(friendly_msg));
}
Err(AdbError::Generic(err))
}
}
}
/// Convert common OEM-specific ADB error messages into user-friendly explanations.
fn make_friendly_error_message(error_output: &str, action: &str) -> String {
// Common Samsung errors
if error_output.contains("DELETE_FAILED_USER_RESTRICTED") {
return format!(
"Cannot uninstall: This package is restricted by the device manufacturer (Samsung Knox or similar).\n\
Error: {error_output}\n\
Tip: Try disabling the package instead, or check device settings for Knox/security restrictions."
);
}
if error_output.contains("NOT_INSTALLED_FOR_USER") {
return format!(
"Package is not installed for the current user.\n\
Error: {error_output}\n\
Tip: The package may be installed for a different user profile or work profile."
);
}
// Empty package name error
if error_output.contains("Shell cannot change component state for null") {
return format!(
"Invalid package: Empty package name detected.\n\
Error: {error_output}\n\
Tip: Please refresh the package list and try again."
);
}
// Generic permission errors
if error_output.contains("Permission denied")
|| error_output.contains("INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE")
{
return format!(
"Permission denied: Insufficient privileges to perform this action.\n\
Error: {error_output}\n\
Tip: This may require root access or the package is protected by the system."
);
}
// Work profile / managed device errors
if error_output.contains("DELETE_FAILED_DEVICE_POLICY_MANAGER") {
return format!(
"Cannot modify: Package is managed by device policy (MDM/EMM).\n\
Error: {error_output}\n\
Tip: Contact your IT administrator if this is a work device."
);
}
// Generic failure with context
format!("{action} -> {error_output}")
}
/// If `None`, returns an empty String, not " --user 0"
#[must_use]
pub fn user_flag(user_id: Option<User>) -> String {
user_id
.map(|user| format!(" --user {}", user.id))
.unwrap_or_default()
}
// Minimum information for processing adb commands
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)]
pub struct CorePackage {
pub name: String,
pub description: String,
#[serde(default)]
pub removal: crate::uad_lists::Removal,
#[serde(default)]
pub state: PackageState,
#[serde(default)]
pub list: crate::uad_lists::UadList,
}
#[must_use]
pub fn apply_pkg_state_commands(
package: &CorePackage,
wanted_state: PackageState,
selected_user: User,
phone: &Phone,
) -> Vec<String> {
// https://github.com/Universal-Debloater-Alliance/universal-android-debloater/wiki/ADB-reference
// ALWAYS PUT THE COMMAND THAT CHANGES THE PACKAGE STATE FIRST!
let commands = match wanted_state {
PackageState::Enabled => match package.state {
PackageState::Disabled => vec!["pm enable"],
PackageState::Uninstalled => match phone.android_sdk {
i if i >= 23 => vec!["cmd package install-existing"],
21 | 22 => vec!["pm unhide"],
19 | 20 => vec!["pm unblock", PM_CLEAR_PACK],
_ => unreachable!("already prevented by the GUI"),
},
_ => vec![],
},
PackageState::Disabled => match package.state {
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"], // > 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![],
},
PackageState::All => vec![],
}; // this should be a `tinyvec`, as `len <= 4`
let user = supports_multi_user(phone).then_some(selected_user);
request_builder(&commands, &package.name, user)
}
/// Build a command request to be sent via ADB to a device.
/// `commands` accepts one or more ADB shell commands
/// which act on a common `package` and `user`.
#[must_use]
pub fn request_builder(commands: &[&str], package: &str, user: Option<User>) -> Vec<String> {
// Defense-in-depth: `package` is interpolated verbatim into a device-shell
// action, so refuse any invalid name/ID. Every current caller already
// reconciles the name against the live device package list before reaching
// here, so this rejects nothing legitimate — it just keeps the no-injection
// 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_none() {
error!("request_builder: refusing invalid package name: {package:?}");
return Vec::new();
}
let maybe_user_flag = user_flag(user);
commands
.iter()
.map(|c| format!("{c}{maybe_user_flag} {package}"))
.collect()
}
/// Get the model by querying the `ro.product.model` property.
///
/// If `serial` is empty, it lets ADB choose the default device.
#[must_use]
pub fn get_device_model(serial: &str) -> String {
AdbCommand::new()
.shell(serial)
.getprop("ro.product.model")
.unwrap_or_else(|err| {
eprintln!("ERROR: {err}");
error!("{err}");
if err.contains("adb: no devices/emulators found") {
"no devices/emulators found".to_string()
} else {
err
}
})
}
/// Get the brand by querying the `ro.product.brand` property.
///
/// If `serial` is empty, it lets ADB choose the default device.
#[must_use]
pub fn get_device_brand(serial: &str) -> String {
AdbCommand::new()
.shell(serial)
.getprop("ro.product.brand")
// `trim` is just-in-case
.map(|s| s.trim().to_string())
.unwrap_or_default()
}
/// Get Android SDK version by querying the
// `ro.build.version.sdk` property or defaulting to 0.
///
/// If `device_serial` is empty, it lets ADB choose the default device.
#[must_use]
pub fn get_android_sdk(device_serial: &str) -> u8 {
AdbCommand::new()
.shell(device_serial)
.getprop("ro.build.version.sdk")
.map_or(0, |sdk| {
sdk.parse().expect("SDK version numeral must be valid")
})
}
/// Capture the current state of a package across all non-protected users.
/// This is used to detect cross-user behavior by comparing before and after states.
///
/// Only includes users where the package exists (Some state). Users where the package
/// doesn't exist (None) are not tracked.
#[must_use]
pub fn capture_cross_user_states(
package_name: &str,
device_serial: &str,
target_user_id: u16,
phone: &Phone,
) -> Vec<(u16, PackageState)> {
phone
.user_list
.iter()
.filter(|u| !u.protected && u.id != target_user_id)
.filter_map(|u| {
verify_package_state(package_name, device_serial, Some(u.id)).map(|state| (u.id, state))
})
.collect()
}
/// Detect cross-user behavior and return appropriate notification message.
/// This handles unexpected cross-user behavior:
/// - Case A: Uninstall → Restore (package appears on other users)
/// - Case B: Uninstall → Uninstall (package disappears from other users that previously had it)
/// - Case C: Restore → Restore (package appears on other users)
#[must_use]
pub fn detect_cross_user_behavior(
package_name: &str,
device_serial: &str,
target_user_id: u16,
wanted_state: PackageState,
actual_state: PackageState,
phone: &Phone,
before_states: &[(u16, PackageState)],
) -> Option<String> {
// Only check if operation was successful on target user
if actual_state != wanted_state {
return None;
}
// Only check if we have multiple users
if phone.user_list.len() < 2 {
return None;
}
let after_states =
check_cross_user_package_existence(package_name, device_serial, target_user_id, phone);
match wanted_state {
PackageState::Uninstalled => {
if after_states.is_empty() {
// Case B: Uninstall → Uninstall (check if all users lost package)
let affected_users: Vec<_> = before_states
.iter()
.filter(|(uid, before_state)| {
// Only flag if the package was installed/enabled/disabled before
*before_state != PackageState::Uninstalled
// And is NOT in after_states (doesn't exist in usable state anymore)
&& !after_states.iter().any(|(after_uid, _)| after_uid == uid)
})
.map(|(uid, _)| uid)
.collect();
if affected_users.is_empty() {
None
} else {
let user_list = affected_users
.iter()
.map(|uid| format!("user {uid}"))
.collect::<Vec<_>>()
.join(", ");
Some(format!(
"Detected cross-user uninstall: package was also uninstalled from {user_list} after uninstalling from user {target_user_id}"
))
}
} else {
// Case A: Uninstall → Restore (package appears on other users)
let user_list = after_states
.iter()
.map(|(uid, state)| format!("user {uid} ({state:?})"))
.collect::<Vec<_>>()
.join(", ");
Some(format!(
"Detected cross-user restoration: package exists on {user_list} after uninstalling from user {target_user_id}"
))
}
}
PackageState::Enabled | PackageState::Disabled => {
// Case C: Restore → Restore (package appears on other users)
// Check if a user didn't have the package before (not tracked or package didn't exist).
// Detects packages that appear on users where they didn't exist previously (OEM cross-user restoration).
let was_package_absent_before = |uid: &u16| {
before_states
.iter()
.find(|(before_uid, _)| before_uid == uid)
.is_none_or(|(_, before_state)| *before_state == PackageState::Uninstalled)
};
let newly_appeared: Vec<_> = after_states
.iter()
.filter(|(uid, _after_state)| was_package_absent_before(uid))
.collect();
if newly_appeared.is_empty() {
None
} else {
let user_list = newly_appeared
.iter()
.map(|(uid, state)| format!("user {uid} ({state:?})"))
.collect::<Vec<_>>()
.join(", ");
Some(format!(
"Detected cross-user restoration: package exists on {user_list} after {} from user {target_user_id}",
if wanted_state == PackageState::Enabled {
"enabling"
} else {
"disabling"
}
))
}
}
PackageState::All => None,
}
}
#[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.
/// `true` isn't reliable, you can only trust `false`.
///
/// See:
/// - <https://source.android.com/docs/devices/admin/multi-user#applying_the_overlay>
/// - <https://developer.android.com/reference/android/os/UserManager#supportsMultipleUsers()>
#[must_use]
pub const fn supports_multi_user(dev: &Phone) -> bool {
// >= Lollipop (5.0)
dev.android_sdk >= 21
}
/// Check if a `user_id` is protected on a device by trying
/// to list associated packages.
///
/// If `device_serial` is empty, it lets ADB choose the default device.
pub fn is_protected_user<S: AsRef<str>>(user_id: u16, device_serial: S) -> bool {
AdbCommand::new()
.shell(device_serial)
.pm()
.list_packages_sys(None, Some(user_id))
.is_err()
}
#[must_use]
pub fn list_users_idx_prot(device_serial: &str) -> Vec<User> {
AdbCommand::new()
.shell(device_serial)
.pm()
.list_users()
.map(|out| {
out.into_iter()
.enumerate()
.map(|(i, user)| {
let id = user.get_id();
User {
id,
index: i,
protected: is_protected_user(id, device_serial),
}
})
.collect()
})
.unwrap_or_default()
}
/// This matches serials (`getprop ro.serialno`)
/// that are authorized by the user.
#[must_use]
pub fn get_devices_list() -> Vec<Phone> {
retry(
Fixed::from_millis(500).take(if cfg!(debug_assertions) { 3 } else { 10 }),
|| match AdbCommand::new().devices() {
Ok(devices) => {
let mut device_list: Vec<Phone> = vec![];
if devices.iter().all(|(_, stat)| stat != "device") {
return OperationResult::Retry(vec![]);
}
for device in devices {
let serial = &device.0;
device_list.push(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.clone(),
});
}
OperationResult::Ok(device_list)
}
Err(err) => {
error!("get_devices_list() -> {err}");
let test: Vec<Phone> = vec![];
OperationResult::Retry(test)
}
},
)
.unwrap_or_default()
}
#[must_use]
pub fn initial_load() -> bool {
match AdbCommand::new().devices() {
Ok(_devices) => true,
Err(_err) => false,
}
}
/// Get the current state of a package on a device
#[must_use]
pub fn get_package_state(
device_serial: &str,
package_name: &str,
user_id: Option<u16>,
) -> Option<PackageState> {
use crate::adb::{ACommand as AdbCommand, PmListPacksFlag};
// Check if package is enabled
if let Ok(enabled_packages) = AdbCommand::new()
.shell(device_serial)
.pm()
.list_packages_sys(Some(PmListPacksFlag::OnlyEnabled), user_id)
&& enabled_packages.contains(&package_name.to_string())
{
return Some(PackageState::Enabled);
}
// Check if package is disabled
if let Ok(disabled_packages) = AdbCommand::new()
.shell(device_serial)
.pm()
.list_packages_sys(Some(PmListPacksFlag::OnlyDisabled), user_id)
&& disabled_packages.contains(&package_name.to_string())
{
return Some(PackageState::Disabled);
}
// Check if package exists at all (including uninstalled)
if let Ok(all_packages) = AdbCommand::new()
.shell(device_serial)
.pm()
.list_packages_sys(Some(PmListPacksFlag::IncludeUninstalled), user_id)
&& all_packages.contains(&package_name.to_string())
{
return Some(PackageState::Uninstalled);
}
// Package not found at all - it doesn't exist on this device/user
None
}
/// Verify the current state of a package on a device.
/// Returns the package state, or `None` if the package doesn't exist.
#[must_use]
pub fn verify_package_state(
package_name: &str,
device_serial: &str,
user_id: Option<u16>,
) -> Option<PackageState> {
get_package_state(device_serial, package_name, user_id)
}
/// Check if a package exists on any other users besides the target user.
/// This helps detect OEM-specific cross-user restoration behavior.
///
/// Only includes users where the package exists in a non-uninstalled state
/// (i.e., Enabled or Disabled).
#[must_use]
pub fn check_cross_user_package_existence(
package_name: &str,
device_serial: &str,
target_user_id: u16,
phone: &Phone,
) -> Vec<(u16, PackageState)> {
let mut other_user_states = Vec::new();
for user in &phone.user_list {
if user.id != target_user_id
&& !user.protected
&& let Some(state) = verify_package_state(package_name, device_serial, Some(user.id))
&& state != PackageState::Uninstalled
{
other_user_states.push((user.id, state));
}
}
other_user_states
}
/// Creates a `CorePackage` with the specified state, preserving other fields from the original.
fn package_with_state(package: &CorePackage, state: PackageState) -> CorePackage {
CorePackage {
state,
..package.clone()
}
}
/// Executes the first available command and returns the result.
fn execute_first_command(commands: &[String], phone: &Phone) -> Result<(), String> {
if commands.is_empty() {
return Err("No command available".to_string());
}
AdbCommand::new()
.shell(&phone.adb_id)
.raw(&commands[0])
.map(|_| ())
.map_err(|err| err.clone())
}
/// Attempt fallback action when package state verification fails
pub fn attempt_fallback(
package: &CorePackage,
wanted_state: PackageState,
actual_state: PackageState,
user: User,
phone: &Phone,
) -> Result<String, String> {
match (wanted_state, actual_state) {
// Case 1: Tried to uninstall but package was reinstalled -> disable it
(PackageState::Uninstalled, PackageState::Enabled) => {
let pkg = package_with_state(package, PackageState::Enabled);
let commands = apply_pkg_state_commands(&pkg, PackageState::Disabled, user, phone);
execute_first_command(&commands, phone)
.map(|()| "disabled package instead of uninstalling".to_string())
.map_err(|e| format!("Failed to disable package: {e}"))
}
// Case 2: Tried to disable but package re-enabled itself -> try uninstall
(PackageState::Disabled, PackageState::Enabled) => {
let pkg = package_with_state(package, PackageState::Enabled);
let commands = apply_pkg_state_commands(&pkg, PackageState::Uninstalled, user, phone);
execute_first_command(&commands, phone)
.map_err(|e| format!("Failed to uninstall: {e}"))?;
// Verify the package was actually uninstalled
match verify_package_state(&package.name, &phone.adb_id, Some(user.id)) {
Some(PackageState::Uninstalled) | None => {
Ok("uninstalled package instead of disabling".to_string())
}
_ => Err("Package still exists after uninstall attempt".to_string()),
}
}
// Case 3: Tried to enable but package was disabled -> try uninstall then reinstall
(PackageState::Enabled, PackageState::Disabled) => {
let pkg = package_with_state(package, PackageState::Disabled);
let uninstall_cmds =
apply_pkg_state_commands(&pkg, PackageState::Uninstalled, user, phone);
execute_first_command(&uninstall_cmds, phone)
.map_err(|e| format!("Failed to uninstall for reinstall: {e}"))?;
// Now try to reinstall/enable
let pkg_uninstalled = package_with_state(package, PackageState::Uninstalled);
let enable_cmds =
apply_pkg_state_commands(&pkg_uninstalled, PackageState::Enabled, user, phone);
if enable_cmds.is_empty() {
return Ok("uninstalled package but couldn't reinstall".to_string());
}
execute_first_command(&enable_cmds, phone)
.map(|()| "uninstalled and reinstalled package to enable it".to_string())
.map_err(|e| format!("Failed to reinstall package: {e}"))
}
// Other cases - no fallback available
_ => Err(format!(
"No fallback available for wanted state {wanted_state:?} and actual state {actual_state:?}"
)),
}
}

View file

@ -1,16 +1,26 @@
use crate::core::utils::{format_diff_time_from_now, last_modified_date};
use crate::CACHE_DIR;
use retry::{delay::Fixed, retry, OperationResult};
use crate::utils::{format_diff_time_from_now, last_modified_date};
use log::warn;
use retry::{OperationResult, delay::Fixed, retry};
use serde::{Deserialize, Serialize};
use serde_json;
use std::borrow::Cow;
use std::collections::HashMap;
use std::fs;
use std::path::{Path, PathBuf};
use std::path::PathBuf;
pub const LIST_FNAME: &str = "uad_lists.json";
#[allow(
clippy::large_include_file,
reason = "https://github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation/discussions/608"
)]
// not `const`, because it's too big
pub static DATA: &str = include_str!("../../../resources/assets/uad_lists.json");
#[derive(Deserialize, Debug, Clone, PartialEq, Hash, Eq)]
#[serde(rename_all = "camelCase")]
pub struct Package {
id: String,
pub list: UadList,
pub description: String,
dependencies: Vec<String>,
@ -19,7 +29,7 @@ pub struct Package {
pub removal: Removal,
}
#[derive(Default, Deserialize, Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[derive(Default, Deserialize, Serialize, Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum UadList {
#[default]
All,
@ -42,7 +52,7 @@ pub enum UadListState {
impl std::fmt::Display for UadListState {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let date = last_modified_date(CACHE_DIR.join("uad_lists.json"));
let date = last_modified_date(CACHE_DIR.join(LIST_FNAME));
let s = match self {
Self::Downloading => "Checking updates...".to_string(),
Self::Done => format!("Done (last was {})", format_diff_time_from_now(date)),
@ -63,24 +73,31 @@ impl UadList {
Self::Pending,
Self::Unlisted,
];
#[must_use]
pub const fn as_str(self) -> &'static str {
match self {
Self::All => "All lists",
Self::Aosp => "aosp",
Self::Carrier => "carrier",
Self::Google => "google",
Self::Misc => "misc",
Self::Oem => "oem",
Self::Pending => "pending",
Self::Unlisted => "unlisted",
}
}
}
impl std::fmt::Display for UadList {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}",
match self {
Self::All => "All lists",
Self::Aosp => "aosp",
Self::Carrier => "carrier",
Self::Google => "google",
Self::Misc => "misc",
Self::Oem => "oem",
Self::Pending => "pending",
Self::Unlisted => "unlisted",
}
)
f.write_str(self.as_str())
}
}
impl From<UadList> for Cow<'_, str> {
fn from(list: UadList) -> Self {
Cow::Borrowed(list.as_str())
}
}
@ -103,7 +120,7 @@ impl std::fmt::Display for PackageState {
f,
"{}",
match self {
Self::All => "All packages",
Self::All => "All states",
Self::Enabled => "Enabled",
Self::Uninstalled => "Uninstalled",
Self::Disabled => "Disabled",
@ -133,15 +150,15 @@ impl Opposite for PackageState {
}
// Bad names. To be changed!
#[derive(Default, Debug, Deserialize, Clone, Copy, PartialEq, Eq, Hash)]
#[derive(Default, Debug, Deserialize, Serialize, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Removal {
All,
#[default]
Recommended,
Advanced,
Expert,
Unsafe,
Unlisted,
All,
}
impl Removal {
@ -153,79 +170,93 @@ impl Removal {
Self::Unsafe,
Self::Unlisted,
];
pub const CATEGORIES: [Self; 5] = [
Self::Recommended,
Self::Advanced,
Self::Expert,
Self::Unsafe,
Self::Unlisted,
];
#[must_use]
pub const fn as_str(self) -> &'static str {
match self {
Self::All => "All removals",
Self::Recommended => "Recommended",
Self::Advanced => "Advanced",
Self::Expert => "Expert",
Self::Unsafe => "Unsafe",
Self::Unlisted => "Unlisted",
}
}
}
impl std::fmt::Display for Removal {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}",
match self {
Self::All => "All",
Self::Recommended => "Recommended",
Self::Advanced => "Advanced",
Self::Expert => "Expert",
Self::Unsafe => "Unsafe",
Self::Unlisted => "Unlisted",
}
)
f.write_str(self.as_str())
}
}
type PackageHashMap = HashMap<String, Package>;
pub fn load_debloat_lists(remote: bool) -> (Result<PackageHashMap, PackageHashMap>, bool) {
let cached_uad_lists: PathBuf = CACHE_DIR.join("uad_lists.json");
impl From<Removal> for Cow<'_, str> {
fn from(list: Removal) -> Self {
Cow::Borrowed(list.as_str())
}
}
pub type PackageHashMap = HashMap<String, Package>;
pub fn load_debloat_lists(remote: bool) -> Result<PackageHashMap, PackageHashMap> {
let cached_uad_lists: PathBuf = CACHE_DIR.join(LIST_FNAME);
let mut error = false;
let list: Vec<Package> = if remote {
let list: PackageHashMap = if remote {
retry(Fixed::from_millis(1000).take(60), || {
match ureq::get(
"https://raw.githubusercontent.com/Universal-Debloater-Alliance/universal-android-debloater/\
main/resources/assets/uad_lists.json",
)
match ureq::get(format!(
"https://raw.githubusercontent.com\
/Universal-Debloater-Alliance\
/universal-android-debloater\
/main\
/resources\
/assets\
/{LIST_FNAME}"
))
.call()
{
Ok(data) => {
let text = data.into_string().expect("response should be Ok type");
Ok(mut data) => {
// https://github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation/discussions/608
let text = data
.body_mut()
.with_config()
.limit(1 << (3 + 10 + 10))
.read_to_string()
.expect("remote list is bigger than 8MiB");
fs::write(cached_uad_lists.clone(), &text).expect("Unable to write file");
let list = serde_json::from_str(&text).expect("Unable to parse");
let list: PackageHashMap =
serde_json::from_str(&text).expect("Unable to parse");
OperationResult::Ok(list)
}
Err(e) => {
warn!("Could not load remote debloat list: {}", e);
warn!("Could not load remote debloat list: {e}");
error = true;
OperationResult::Retry(Vec::<Package>::new())
OperationResult::Retry(PackageHashMap::new())
}
}
})
.map_or_else(|_| get_local_lists(), |list| list)
.unwrap_or_else(|_| get_local_lists())
} else {
warn!("Could not load remote debloat list");
get_local_lists()
};
// TODO: Do it without intermediary Vec?
let mut package_lists = HashMap::new();
for p in list {
let name = p.id.clone();
package_lists.insert(name, p);
}
if error {
(Err(package_lists), remote)
} else {
(Ok(package_lists), remote)
}
(if error { Err } else { Ok })(list)
}
fn get_local_lists() -> Vec<Package> {
const DATA: &str = include_str!("../../resources/assets/uad_lists.json");
let cached_uad_lists = CACHE_DIR.join("uad_lists.json");
if Path::new(&cached_uad_lists).exists() {
let data = fs::read_to_string(cached_uad_lists).unwrap();
serde_json::from_str(&data).expect("Unable to parse")
} else {
serde_json::from_str(DATA).expect("Unable to parse")
}
fn get_local_lists() -> PackageHashMap {
let cached_uad_lists = CACHE_DIR.join(LIST_FNAME);
serde_json::from_str(
fs::read_to_string(cached_uad_lists)
.as_deref()
.unwrap_or(DATA),
)
.expect("Unable to parse")
}
#[cfg(test)]
@ -233,7 +264,6 @@ mod tests {
use super::*;
#[test]
fn test_parse_json() {
const DATA: &str = include_str!("../../resources/assets/uad_lists.json");
let _: Vec<Package> = serde_json::from_str(DATA).expect("Unable to parse");
let _: PackageHashMap = serde_json::from_str(DATA).expect("Unable to parse");
}
}

View file

@ -2,7 +2,9 @@ use serde::Deserialize;
#[cfg(feature = "self-update")]
use {
retry::{delay::Fibonacci, retry, OperationResult},
crate::utils::NAME,
log::{debug, error},
retry::{OperationResult, delay::Fibonacci, retry},
std::fs,
std::io,
std::io::copy,
@ -52,15 +54,15 @@ impl std::fmt::Display for SelfUpdateStatus {
/// Download a file from the internet
#[cfg(feature = "self-update")]
pub async fn download_file<T: ToString + Send>(url: T, dest_file: PathBuf) -> Result<(), String> {
let url = url.to_string();
debug!("downloading file from {}", &url);
#[allow(clippy::unused_async, reason = "`.call` is equivalent to `.await`")]
pub async fn download_file(url: &str, dest_file: PathBuf) -> Result<(), String> {
debug!("downloading file from {url}");
match ureq::get(&url).call() {
Ok(res) => {
match ureq::get(url).call() {
Ok(mut res) => {
let mut file = fs::File::create(dest_file).map_err(|e| e.to_string())?;
if let Err(e) = copy(&mut res.into_reader(), &mut file) {
if let Err(e) = copy(&mut res.body_mut().as_reader(), &mut file) {
return Err(e.to_string());
}
}
@ -74,7 +76,7 @@ pub async fn download_file<T: ToString + Send>(url: T, dest_file: PathBuf) -> Re
/// then returns both the original file name (new version) and temp path (old version)
#[cfg(feature = "self-update")]
pub async fn download_update_to_temp_file(
bin_name: String,
bin_name: &str,
release: Release,
) -> Result<(PathBuf, PathBuf), ()> {
let current_bin_path = std::env::current_exe().map_err(|_| ())?;
@ -107,13 +109,13 @@ pub async fn download_update_to_temp_file(
let archive_path = current_bin_path.parent().ok_or(())?.join(&asset_name);
if let Err(e) = download_file(asset.download_url, archive_path.clone()).await {
error!("Couldn't download UAD update: {}", e);
if let Err(e) = download_file(&asset.download_url, archive_path.clone()).await {
error!("Couldn't download {NAME} update: {e}");
return Err(());
}
if extract_binary_from_tar(&archive_path, &download_path).is_err() {
error!("Couldn't extract UAD release tarball");
error!("Couldn't extract {NAME} release tarball");
return Err(());
}
@ -130,8 +132,8 @@ pub async fn download_update_to_temp_file(
.cloned()
.ok_or(())?;
if let Err(e) = download_file(asset.download_url, download_path.clone()).await {
error!("Couldn't download UAD update: {}", e);
if let Err(e) = download_file(&asset.download_url, download_path.clone()).await {
error!("Couldn't download {NAME} update: {}", e);
return Err(());
}
}
@ -144,17 +146,17 @@ pub async fn download_update_to_temp_file(
let mut permissions = fs::metadata(&download_path).map_err(|_| ())?.permissions();
permissions.set_mode(0o755);
if let Err(e) = fs::set_permissions(&download_path, permissions) {
error!("[SelfUpdate] Couldn't set permission to temp file: {}", e);
error!("[SelfUpdate] Couldn't set permission to temp file: {e}");
return Err(());
}
}
if let Err(e) = rename(&current_bin_path, &tmp_path) {
error!("[SelfUpdate] Couldn't rename binary path: {}", e);
error!("[SelfUpdate] Couldn't rename from current to temporary binary path: {e}");
return Err(());
}
if let Err(e) = rename(&download_path, &current_bin_path) {
error!("[SelfUpdate] Couldn't rename binary path: {}", e);
error!("[SelfUpdate] Couldn't rename from downloaded to current binary path: {e}");
return Err(());
}
@ -166,37 +168,34 @@ pub fn get_latest_release() -> Result<Option<Release>, ()> {
Ok(None)
}
// UAD only has pre-releases so we can't use
// UAD-ng only has pre-releases so we can't use
// https://api.github.com/repos/Universal-Debloater-Alliance/universal-android-debloater/releases/latest
// to only get the latest release
#[cfg(feature = "self-update")]
pub fn get_latest_release() -> Result<Option<Release>, ()> {
debug!("Checking for UAD update");
debug!("Checking for {NAME} update");
match ureq::get("https://api.github.com/repos/Universal-Debloater-Alliance/universal-android-debloater/releases")
.call()
{
Ok(res) => {
let release: Release = serde_json::from_value(
res.into_json::<serde_json::Value>()
.map_err(|_| ())?
.get(0)
.ok_or(())?
.clone(),
)
.map_err(|_| ())?;
if release.tag_name.as_str() != "dev-build"
&& release.tag_name.as_str() > env!("CARGO_PKG_VERSION")
{
Ok(Some(release))
} else {
Ok(None)
}
}
Err(_) => {
debug!("Failed to check UAD update");
Err(())
if let Ok(mut res) = ureq::get("https://api.github.com/repos/Universal-Debloater-Alliance/universal-android-debloater/releases/latest")
.call() {
let release: Release = serde_json::from_value(
res.body_mut().read_json::<serde_json::Value>()
.map_err(|_| ())?
.clone(),
)
.map_err(|_| ())?;
let release_version = release.tag_name.strip_prefix('v').unwrap_or(&release.tag_name);
if release_version != "dev-build"
&& release_version > env!("CARGO_PKG_VERSION")
{
Ok(Some(release))
} else {
Ok(None)
}
} else {
debug!("Failed to check {NAME} update");
Err(())
}
}
@ -224,24 +223,29 @@ pub fn extract_binary_from_tar(archive_path: &Path, temp_file: &Path) -> io::Res
}
/// Hardcoded binary names for each compilation target
/// that gets published to the Github Release
/// that gets published to the GitHub Release
#[cfg(feature = "self-update")]
pub const fn bin_name() -> &'static str {
pub const BIN_NAME: &str = {
#[cfg(target_os = "windows")]
{
"uad_gui.exe"
"uad-ng-windows.exe"
}
#[cfg(target_os = "macos")]
#[cfg(all(target_os = "macos", any(target_arch = "x86_64", target_arch = "x86")))]
{
"uad_gui-macos"
"uad-ng-macos-intel"
}
#[cfg(all(target_os = "macos", any(target_arch = "arm", target_arch = "aarch64")))]
{
"uad-ng-macos"
}
#[cfg(not(any(target_os = "macos", target_os = "windows")))]
{
"uad_gui-linux"
"uad-ng-linux"
}
}
};
/// Rename a file or directory to a new name, retrying if the operation fails because of permissions
///
@ -261,7 +265,7 @@ where
retry(Fibonacci::from_millis(1).take(21), || {
match fs::rename(from, to) {
Ok(_) => OperationResult::Ok(()),
Ok(()) => OperationResult::Ok(()),
Err(e) => match e.kind() {
io::ErrorKind::PermissionDenied => OperationResult::Retry(e),
_ => OperationResult::Err(e),
@ -288,7 +292,7 @@ where
retry(
Fibonacci::from_millis(1).take(21),
|| match fs::remove_file(path) {
Ok(_) => OperationResult::Ok(()),
Ok(()) => OperationResult::Ok(()),
Err(e) => match e.kind() {
io::ErrorKind::PermissionDenied => OperationResult::Retry(e),
_ => OperationResult::Err(e),

View file

@ -0,0 +1,299 @@
#![warn(clippy::unwrap_used)]
use crate::{
adb::{ACommand as AdbCommand, PmListPacksFlag},
sync::{CorePackage, User},
uad_lists::{PackageHashMap, PackageState, Removal, UadList},
};
use chrono::{DateTime, offset::Utc};
use csv::Writer;
use log::error;
use std::{
collections::HashSet,
fmt, fs,
path::{Path, PathBuf},
};
/// Canonical shortened name of the application
pub const NAME: &str = "UAD-ng";
/// Full name of the application
pub const FULL_NAME: &str = "Universal Android Debloater Next Generation";
pub const EXPORT_FILE_NAME: &str = "selection_export.txt";
/// Returns `true` if `c` matches the regex `\w`
#[inline]
#[must_use]
pub const fn is_w(c: u8) -> bool {
// https://github.com/rust-lang/rust/issues/93279
// https://github.com/rust-lang/rust/issues/83623
(c == b'_') | c.is_ascii_alphanumeric()
}
/// Returns `true` if `s` matches the regex `^\w+$`
#[must_use]
pub const fn is_all_w_c(s: &[u8]) -> bool {
let mut i = 0;
while i < s.len() {
if !is_w(s[i]) {
return false;
}
i += 1;
}
true
}
// Takes a time-stamp parameter,
// for purity and testability.
//
// The TZ is generic, because testing requires UTC,
// while users get the local-aware version.
#[expect(
clippy::needless_pass_by_value,
reason = "Timestamps should be fresh, no need to borrow"
)]
#[must_use]
pub fn generate_backup_name<T>(t: DateTime<T>) -> String
where
T: chrono::TimeZone,
T::Offset: std::fmt::Display,
{
t.format("uninstalled_packages_%Y%m%d.csv").to_string()
}
#[derive(Debug, Clone, Copy)]
pub enum Error {
DialogClosed,
}
#[must_use]
pub fn fetch_packages(
uad_lists: &PackageHashMap,
device_serial: &str,
user_id: Option<u16>,
) -> Vec<CorePackage> {
let all_sys_packs = AdbCommand::new()
.shell(device_serial)
.pm()
.list_packages_sys(Some(PmListPacksFlag::IncludeUninstalled), user_id)
.unwrap_or_default();
let enabled_sys_packs: HashSet<String> = AdbCommand::new()
.shell(device_serial)
.pm()
.list_packages_sys(Some(PmListPacksFlag::OnlyEnabled), user_id)
.unwrap_or_default()
.into_iter()
.collect();
let disabled_sys_packs: HashSet<String> = AdbCommand::new()
.shell(device_serial)
.pm()
.list_packages_sys(Some(PmListPacksFlag::OnlyDisabled), user_id)
.unwrap_or_default()
.into_iter()
.collect();
let mut description;
let mut removal;
let mut state;
let mut list;
let mut user_package: Vec<CorePackage> = Vec::new();
for pack_name in all_sys_packs {
let p_name = &pack_name;
description = String::from("[No description]: CONTRIBUTION WELCOMED");
removal = Removal::Unlisted;
state = PackageState::Uninstalled;
list = UadList::Unlisted;
if let Some(package) = uad_lists.get(p_name) {
if !package.description.is_empty() {
description = package.description.clone();
}
removal = package.removal;
list = package.list;
}
if enabled_sys_packs.contains(p_name) {
state = PackageState::Enabled;
} else if disabled_sys_packs.contains(p_name) {
state = PackageState::Disabled;
}
let package = CorePackage {
name: p_name.clone(),
description,
removal,
state,
list,
};
user_package.push(package);
}
user_package.sort_by_key(|package| package.name.to_lowercase());
user_package
}
#[must_use]
pub fn setup_uad_dir(dir: &Path) -> PathBuf {
let dir = dir.join("uad");
if let Err(e) = fs::create_dir_all(&dir) {
error!("Can't create directory: {}", dir.display());
panic!("{e}");
}
dir
}
/// Open a directory or file with the system's default file manager.
pub fn open_url(dir: PathBuf) {
const OPENER: &str = match std::env::consts::OS.as_bytes() {
b"windows" => "explorer",
b"macos" => "open",
// "linux"
_ => "xdg-open",
};
match std::process::Command::new(OPENER).arg(dir).output() {
Ok(o) => {
if !o.status.success() {
// Use lossy conversion for stderr - some systems (like Windows)
// may output non-UTF8 characters in error messages
let stderr = String::from_utf8_lossy(&o.stderr);
let stderr_trimmed = stderr.trim_end();
if stderr_trimmed.is_empty() {
error!("Can't open URL: command failed with no error message");
} else {
error!("Can't open the following URL: {stderr_trimmed}");
}
}
}
Err(e) => error!("Failed to run command to open the file explorer: {e}"),
}
}
#[rustfmt::skip]
#[must_use]
pub fn last_modified_date(file: PathBuf) -> DateTime<Utc> {
fs::metadata(file).map_or_else(|_| Utc::now(), |metadata| match metadata.modified() {
Ok(time) => time.into(),
Err(_) => Utc::now(),
})
}
#[must_use]
pub fn format_diff_time_from_now(date: DateTime<Utc>) -> String {
let now: DateTime<Utc> = Utc::now();
let last_update = now - date;
if last_update.num_days() == 0 {
if last_update.num_hours() == 0 {
last_update.num_minutes().to_string() + " min(s) ago"
} else {
last_update.num_hours().to_string() + " hour(s) ago"
}
} else {
last_update.num_days().to_string() + " day(s) ago"
}
}
/// Export selected package names.
/// File will be saved in same directory where UAD-ng is located.
pub fn export_selection(package_names: &[String]) -> Result<bool, String> {
let selected = package_names.join("\n");
match fs::write(EXPORT_FILE_NAME, selected) {
Ok(()) => Ok(true),
Err(err) => Err(err.to_string()),
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct DisplayablePath {
pub path: PathBuf,
}
impl fmt::Display for DisplayablePath {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let stem = self.path.file_stem().map_or_else(
|| {
error!("[PATH STEM]: No file stem found");
"[File steam not found]".to_string()
},
|p| {
if let Ok(stem) = p.to_os_string().into_string() {
stem
} else {
error!("[PATH ENCODING]: {}", self.path.display());
"[PATH ENCODING ERROR]".to_string()
}
},
);
write!(f, "{stem}")
}
}
/// Export uninstalled packages in a csv file.
/// Exported information will contain package name and description.
pub fn export_packages(user: User, phone_packages: &[Vec<CorePackage>]) -> Result<bool, String> {
let backup_file = generate_backup_name(chrono::Local::now());
let file = fs::File::create(backup_file).map_err(|err| err.to_string())?;
let mut wtr = Writer::from_writer(file);
wtr.write_record(["Package Name", "Description"])
.map_err(|err| err.to_string())?;
let uninstalled_packages: Vec<&CorePackage> = phone_packages[user.index]
.iter()
.filter(|p| p.state == PackageState::Uninstalled)
.collect();
for package in uninstalled_packages {
wtr.write_record([&package.name, &package.description.replace('\n', " ")])
.map_err(|err| err.to_string())?;
}
wtr.flush().map_err(|err| err.to_string())?;
Ok(true)
}
/// Truncate description to fit within max length, taking only the first line
#[must_use]
pub fn truncate_description(desc: &str, max_len: usize) -> String {
let first_line = desc.split('\n').next().unwrap_or("").trim_end();
if first_line.len() <= max_len {
first_line.to_string()
} else {
format!("{}...", &first_line[..max_len.saturating_sub(3)])
}
}
/// Check if package matches search term (checks name and description)
#[must_use]
pub fn matches_search(pkg_name: &str, search_term: &str, pkg_description: Option<&str>) -> bool {
let search_lower = search_term.to_lowercase();
if pkg_name.to_lowercase().contains(&search_lower) {
return true;
}
if let Some(description) = pkg_description {
if description.to_lowercase().contains(&search_lower) {
return true;
}
}
false
}
#[cfg(test)]
mod tests {
use super::*;
use chrono::TimeZone;
#[test]
fn backup_name() {
assert_eq!(
generate_backup_name(chrono::Utc.timestamp_millis_opt(0).unwrap()),
"uninstalled_packages_19700101.csv".to_string()
);
}
}

62
crates/uad-gui/Cargo.toml Normal file
View file

@ -0,0 +1,62 @@
[package]
name = "uad-gui"
version.workspace = true
authors.workspace = true
license.workspace = true
homepage.workspace = true
repository.workspace = true
readme.workspace = true
keywords.workspace = true
categories = ["gui"]
edition.workspace = true
[[bin]]
name = "uad-ng"
path = "src/main.rs"
[features]
default = ["wgpu", "self-update", "img"]
wgpu = [] # Iced/wgpu is default
self-update = ["flate2", "tar"]
no-self-update = []
img = ["image", "iced/image"]
[dependencies]
uad-core = { path = "../uad-core", features = ["self-update"] }
iced.workspace = true
image = { workspace = true, optional = true }
rfd.workspace = true
dark-light.workspace = true
fern.workspace = true
chrono.workspace = true
dirs.workspace = true
log.workspace = true
flate2 = { workspace = true, optional = true }
tar = { workspace = true, optional = true }
[target.'cfg(target_os = "windows")'.dependencies]
win32console.workspace = true
[build-dependencies]
embed-resource = "3"
[lints.rust]
deprecated_safe = "warn"
[lints.clippy]
undocumented_unsafe_blocks = "forbid"
exit = "deny"
panic_in_result_fn = "warn"
infinite_loop = "warn"
mem_forget = "warn"
implicit_clone = "warn"
format_push_string = "warn"
large_include_file = "warn"
shadow_unrelated = "warn"
struct_field_names = "allow" # annoying
disallowed_types = "deny"
disallowed_methods = "deny"
allow_attributes_without_reason = "warn"
pedantic = { level = "warn", priority = -1 }

475
crates/uad-gui/src/gui.rs Normal file
View file

@ -0,0 +1,475 @@
#[cfg(feature = "img")]
use crate::theme::OS_COLOR_SCHEME;
use crate::theme::Theme;
use crate::theme::string_to_theme;
use crate::views::about::{About as AboutView, Message as AboutMessage};
use crate::views::list::{
List as AppsView, LoadingState as ListLoadingState, Message as AppsMessage,
};
use crate::views::settings::{Message as SettingsMessage, Settings as SettingsView};
use crate::widgets::navigation_menu::nav_menu;
use iced::font;
use iced::widget::column;
#[cfg(feature = "img")]
use iced::window::icon;
use iced::{Alignment, Element, Length, Settings, Task, window::Settings as Window};
use iced::{Subscription, event, keyboard};
#[cfg(feature = "img")]
use image::ImageFormat;
use log::{debug, error, info};
#[cfg(feature = "self-update")]
use std::path::PathBuf;
use uad_core::adb;
use uad_core::sync::{Phone, get_devices_list, initial_load};
use uad_core::uad_lists::UadListState;
use uad_core::update::{Release, SelfUpdateState, SelfUpdateStatus, get_latest_release};
use uad_core::utils::{FULL_NAME, NAME};
#[cfg(feature = "self-update")]
use uad_core::update::{BIN_NAME, download_update_to_temp_file, remove_file};
#[derive(Default, Debug, Clone)]
enum View {
#[default]
List,
About,
Settings,
}
#[derive(Default, Clone)]
pub struct UpdateState {
pub self_update: SelfUpdateState,
pub uad_list: UadListState,
}
#[derive(Default)]
pub struct UadGui {
view: View,
apps_view: AppsView,
about_view: AboutView,
settings_view: SettingsView,
devices_list: Vec<Phone>,
/// index of `devices_list`
selected_device: Option<Phone>,
update_state: UpdateState,
nb_running_async_adb_commands: u32,
adb_satisfied: bool,
}
#[derive(Debug, Clone)]
pub enum Message {
/// Navigation Panel
AboutPressed,
SettingsPressed,
AppsPress,
DeviceSelected(Phone),
AboutAction(AboutMessage),
AppsAction(AppsMessage),
SettingsAction(SettingsMessage),
RefreshButtonPressed,
RebootButtonPressed,
LoadDevices(Vec<Phone>),
#[cfg(feature = "self-update")]
_NewReleaseDownloaded(Result<(PathBuf, PathBuf), ()>),
GetLatestRelease(Result<Option<Release>, ()>),
FontLoaded(Result<(), iced::font::Error>),
Nothing,
ADBSatisfied(bool),
}
impl UadGui {
#[allow(
clippy::unused_self,
reason = "required by iced's Application trait interface"
)]
fn title(&self) -> String {
self.selected_device.as_ref().map_or_else(
|| FULL_NAME.to_string(),
|device| format!("{FULL_NAME} - {}", device.model),
)
}
fn new() -> (Self, Task<Message>) {
(
Self::default(),
Task::batch([
// Used in crate::widgets::navigation_menu::ICONS. Name is `icomoon`.
font::load(include_bytes!("../../../resources/assets/icons.ttf").as_slice())
.map(Message::FontLoaded),
Task::perform(async { initial_load() }, Message::ADBSatisfied),
Task::perform(async { get_devices_list() }, Message::LoadDevices),
Task::perform(
async move { get_latest_release() },
Message::GetLatestRelease,
),
]),
)
}
#[allow(
clippy::unused_self,
reason = "required by iced's Application trait interface"
)]
fn subscription(&self) -> Subscription<Message> {
if self.selected_device.is_some() {
event::listen_with(Self::keyboard_shortcuts_with_device)
} else {
event::listen_with(Self::keyboard_shortcuts_without_device)
}
}
fn keyboard_shortcuts_with_device(
event: iced::Event,
_status: iced::event::Status,
_window: iced::window::Id,
) -> Option<Message> {
Self::keyboard_shortcuts(event, true)
}
fn keyboard_shortcuts_without_device(
event: iced::Event,
_status: iced::event::Status,
_window: iced::window::Id,
) -> Option<Message> {
Self::keyboard_shortcuts(event, false)
}
fn keyboard_shortcuts(event: iced::Event, can_control_device: bool) -> Option<Message> {
match event {
iced::Event::Keyboard(keyboard::Event::KeyPressed {
key: keyboard::Key::Character(c),
modifiers,
..
}) if modifiers.control() && modifiers.shift() => match c.as_str() {
"r" if can_control_device => Some(Message::RebootButtonPressed),
"5" if can_control_device => Some(Message::RefreshButtonPressed),
"a" => Some(Message::AppsPress),
"i" => Some(Message::AboutPressed),
"s" => Some(Message::SettingsPressed),
_ => None,
},
_ => None,
}
}
#[allow(
clippy::too_many_lines,
reason = "Root GUI update orchestrates many flows"
)]
fn update(&mut self, msg: Message) -> Task<Message> {
match msg {
Message::LoadDevices(devices_list) => {
self.selected_device = match &self.selected_device {
Some(s_device) => {
// Try to reload last selected phone
devices_list
.iter()
.find(|phone| phone.adb_id == s_device.adb_id)
.cloned()
}
None => devices_list.first().cloned(),
};
self.devices_list = devices_list;
#[expect(unused_must_use, reason = "side-effect")]
{
self.update(Message::SettingsAction(SettingsMessage::LoadDeviceSettings));
}
self.update(Message::AppsAction(AppsMessage::LoadUadList(true)))
}
Message::AppsPress => {
self.view = View::List;
Task::none()
}
Message::AboutPressed => {
self.view = View::About;
self.update_state.self_update = SelfUpdateState::default();
Task::perform(
async move { get_latest_release() },
Message::GetLatestRelease,
)
}
Message::SettingsPressed => {
self.view = View::Settings;
Task::none()
}
Message::RefreshButtonPressed => {
self.apps_view = AppsView::default();
#[expect(unused_must_use, reason = "side-effect")]
{
self.update(Message::AppsAction(AppsMessage::ADBSatisfied(
self.adb_satisfied,
)));
}
Task::perform(async { get_devices_list() }, Message::LoadDevices)
}
Message::RebootButtonPressed => {
self.apps_view = AppsView::default();
let serial = match &self.selected_device {
Some(d) => d.adb_id.clone(),
_ => String::default(),
};
self.selected_device = None;
self.devices_list = vec![];
Task::perform(
async { adb::ACommand::new().shell(serial).reboot() },
|_| Message::Nothing,
)
}
Message::AppsAction(msg) => self
.apps_view
.update(
&mut self.settings_view,
&mut self.selected_device.clone().unwrap_or_default(),
&mut self.update_state.uad_list,
msg,
)
.map(Message::AppsAction),
Message::SettingsAction(msg) => {
match msg {
SettingsMessage::RestoringDevice(ref output) => {
self.nb_running_async_adb_commands -= 1;
self.view = View::List;
#[expect(unused_must_use, reason = "side-effect")]
{
self.apps_view.update(
&mut self.settings_view,
&mut self.selected_device.clone().unwrap_or_default(),
&mut self.update_state.uad_list,
AppsMessage::RestoringDevice(output.clone()),
);
}
if self.nb_running_async_adb_commands == 0 {
return self.update(Message::RefreshButtonPressed);
}
}
SettingsMessage::MultiUserMode(toggled) if toggled => {
for user in self.apps_view.phone_packages.clone() {
for (i, _) in user.iter().filter(|&pkg| pkg.selected).enumerate() {
for u in self
.selected_device
.as_ref()
.expect("Device should be selected")
.user_list
.iter()
.filter(|&u| !u.protected)
{
self.apps_view.phone_packages[u.index][i].selected = true;
}
}
}
}
_ => (),
}
self.settings_view
.update(
&self.selected_device.clone().unwrap_or_default(),
&self.apps_view.phone_packages,
&mut self.nb_running_async_adb_commands,
msg,
self.apps_view.selected_user,
)
.map(Message::SettingsAction)
}
Message::AboutAction(msg) => {
self.about_view.update(msg.clone());
match msg {
AboutMessage::UpdateUadLists => {
self.update_state.uad_list = UadListState::Downloading;
self.apps_view.loading_state = ListLoadingState::DownloadingList;
self.update(Message::AppsAction(AppsMessage::LoadUadList(true)))
}
AboutMessage::DoSelfUpdate => {
#[cfg(feature = "self-update")]
if let Some(release) = self.update_state.self_update.latest_release.as_ref()
{
self.update_state.self_update.status = SelfUpdateStatus::Updating;
self.apps_view.loading_state = ListLoadingState::_UpdatingUad;
Task::perform(
download_update_to_temp_file(BIN_NAME, release.clone()),
Message::_NewReleaseDownloaded,
)
} else {
Task::none()
}
#[cfg(not(feature = "self-update"))]
Task::none()
}
AboutMessage::UrlPressed(_) => Task::none(),
}
}
Message::DeviceSelected(s_device) => {
self.selected_device = Some(s_device.clone());
self.view = View::List;
info!("{:-^65}", "-");
info!(
"ANDROID_SDK: {} | DEVICE: {}",
s_device.android_sdk, s_device.model
);
info!("{:-^65}", "-");
self.apps_view.loading_state = ListLoadingState::FindingPhones;
#[expect(unused_must_use, reason = "side-effects")]
{
self.update(Message::SettingsAction(SettingsMessage::LoadDeviceSettings));
self.update(Message::AppsAction(AppsMessage::ToggleAllSelected(false)));
self.update(Message::AppsAction(AppsMessage::ClearSelectedPackages));
}
self.update(Message::AppsAction(AppsMessage::LoadPhonePackages((
self.apps_view.uad_lists.clone(),
UadListState::Done,
))))
}
#[cfg(feature = "self-update")]
Message::_NewReleaseDownloaded(res) => {
debug!("{NAME} update has been downloaded!");
if let Ok((relaunch_path, cleanup_path)) = res {
let mut args: Vec<_> = std::env::args().skip(1).collect();
// Remove the `--self-update-temp` arg from args if it exists,
// since we need to pass it cleanly. Otherwise new process will
// fail during arg parsing.
if let Some(idx) = args.iter().position(|a| a == "--self-update-temp") {
args.remove(idx);
// Remove path passed after this arg
args.remove(idx);
}
match std::process::Command::new(relaunch_path)
.args(args)
.arg("--self-update-temp")
.arg(&cleanup_path)
.spawn()
{
Ok(_) => {
if let Err(e) = remove_file(cleanup_path) {
error!("Could not remove temp update file: {e}");
}
std::process::exit(0)
}
Err(error) => {
if let Err(e) = remove_file(cleanup_path) {
error!("Could not remove temp update file: {e}");
}
error!("Failed to update {NAME}: {error}");
}
}
} else {
error!("Failed to update {NAME}!");
#[expect(unused_must_use, reason = "side-effect")]
{
self.update(Message::AppsAction(AppsMessage::UpdateFailed));
self.update_state.self_update.status = SelfUpdateStatus::Failed;
}
}
Task::none()
}
Message::GetLatestRelease(release) => {
match release {
Ok(r) => {
self.update_state.self_update.status = SelfUpdateStatus::Done;
self.update_state.self_update.latest_release = r;
}
Err(()) => self.update_state.self_update.status = SelfUpdateStatus::Failed,
}
Task::none()
}
Message::FontLoaded(result) => {
if let Err(error) = result {
error!("Couldn't load font: {error:?}");
}
Task::none()
}
Message::ADBSatisfied(result) => {
self.adb_satisfied = result;
self.update(Message::AppsAction(AppsMessage::ADBSatisfied(
self.adb_satisfied,
)))
}
Message::Nothing => Task::none(),
}
}
fn view(&self) -> Element<'_, Message, Theme> {
let navigation_container = nav_menu(
&self.devices_list,
self.selected_device.clone(),
&self.apps_view,
&self.update_state.self_update,
);
let selected_device = self.selected_device.clone().unwrap_or_default();
let main_container = match self.view {
View::List => self
.apps_view
.view(&self.settings_view, &selected_device)
.map(Message::AppsAction),
View::About => self
.about_view
.view(&self.update_state)
.map(Message::AboutAction),
View::Settings => self
.settings_view
.view(&selected_device, &self.apps_view)
.map(Message::SettingsAction),
};
column![navigation_container, main_container]
.width(Length::Fill)
.align_x(Alignment::Center)
.into()
}
fn theme(&self) -> Theme {
string_to_theme(&self.settings_view.general.theme)
}
}
impl UadGui {
pub fn start() -> iced::Result {
#[cfg(feature = "img")]
let logo: &[u8] = match *OS_COLOR_SCHEME {
// remember to keep `Unspecified` in sync with `src/theme`
dark_light::Mode::Dark | dark_light::Mode::Unspecified => {
include_bytes!("../../../resources/assets/logo-dark.png")
}
dark_light::Mode::Light => {
include_bytes!("../../../resources/assets/logo-light.png")
}
};
iced::application(UadGui::new, UadGui::update, UadGui::view)
.title(UadGui::title)
.theme(UadGui::theme)
.subscription(UadGui::subscription)
.settings(Settings {
id: Some(String::from(NAME)),
default_text_size: iced::Pixels(16.0),
// HACK: avoid glyph clipping on some systems. Details:
// https://github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation/pull/1337
#[cfg(target_os = "linux")]
default_font: iced::Font {
family: iced::font::Family::Name("Adwaita Sans"),
..Default::default()
},
..Settings::default()
})
.window(Window {
size: iced::Size {
width: 950.0,
height: 700.0,
},
resizable: true,
decorations: true,
#[cfg(feature = "img")]
icon: icon::from_file_data(logo, Some(ImageFormat::Png)).ok(),
..iced::window::Settings::default()
})
.run()
}
}

View file

@ -0,0 +1,23 @@
use crate::style;
use crate::theme::Theme;
use iced::Element;
use iced::widget::button::Button;
/// Wrapper function for `iced::widget::button` with padding and style applied
pub fn button_primary<'a, Message>(
content: impl Into<Element<'a, Message, Theme>>,
) -> Button<'a, Message, Theme> {
iced::widget::button(content)
.padding([5, 10])
.style(style::Button::Primary)
}
/// Opens a file picker dialog to select a folder
pub async fn open_folder() -> Result<std::path::PathBuf, uad_core::utils::Error> {
rfd::AsyncFileDialog::new()
.set_title("Choose a backup location")
.pick_folder()
.await
.ok_or(uad_core::utils::Error::DialogClosed)
.map(|f| f.path().to_path_buf())
}

11
crates/uad-gui/src/lib.rs Normal file
View file

@ -0,0 +1,11 @@
#![allow(
clippy::missing_errors_doc,
reason = "Short-circuit doc lint to keep CI green"
)]
pub mod gui;
pub mod helpers;
pub mod style;
pub mod theme;
pub mod views;
pub mod widgets;

112
crates/uad-gui/src/main.rs Normal file
View file

@ -0,0 +1,112 @@
#![windows_subsystem = "windows"]
use fern::{
FormatCallback,
colors::{Color, ColoredLevelConfig},
};
use log::Record;
use std::sync::LazyLock;
use std::{fmt::Arguments, fs::OpenOptions, path::PathBuf};
use uad_core::utils::setup_uad_dir;
use uad_gui::gui::UadGui;
static CACHE_DIR: LazyLock<PathBuf> =
LazyLock::new(|| setup_uad_dir(&dirs::cache_dir().expect("Can't detect cache dir")));
fn main() -> iced::Result {
// Safety: This function is safe to call in a single-threaded program.
// The exact requirement is: you must ensure that there are no other threads concurrently writing or
// reading(!) the environment through functions or global variables other than the ones in this module.
unsafe {
// Force WGPU/Iced to use discrete GPU to prevent crashes on PCs with two GPUs.
// See #848 and related pull 850.
std::env::set_var("WGPU_POWER_PREF", "high");
}
setup_logger().expect("setup logging");
UadGui::start()
}
/// Sets up logging to a new file in `CACHE_DIR"/uadng.log"`
/// Also attaches the terminal on Windows machines
/// '''
/// match `setup_logger().expect("Error` setting up logger")
/// '''
fn setup_logger() -> Result<(), fern::InitError> {
#[cfg(target_os = "windows")]
{
attach_windows_console();
}
let colors = ColoredLevelConfig::new().info(Color::Green);
let make_formatter = |use_colors: bool| {
move |out: FormatCallback, message: &Arguments, record: &Record| {
out.finish(format_args!(
"{} {} [{}:{}] {}",
chrono::Local::now().format("%Y-%m-%d %H:%M:%S"),
if use_colors {
format!("{:5}", colors.color(record.level()))
} else {
format!("{:5}", record.level().to_string())
},
record.file().unwrap_or("?"),
record.line().map(|l| l.to_string()).unwrap_or_default(),
message
));
}
};
let default_log_level = log::LevelFilter::Warn;
let log_file = OpenOptions::new()
.create(true)
.append(true)
.truncate(false)
.open(CACHE_DIR.join("uadng.log"))?;
let file_dispatcher = fern::Dispatch::new()
.format(make_formatter(false))
.level(default_log_level)
// Rust compiler makes module names use _ instead of -
.level_for("uad_gui", log::LevelFilter::Debug)
.chain(log_file);
let stdout_dispatcher = fern::Dispatch::new()
.format(make_formatter(true))
.level(default_log_level)
// Rust compiler makes module names use _ instead of -
.level_for("uad_gui", log::LevelFilter::Warn)
.chain(std::io::stdout());
fern::Dispatch::new()
.chain(stdout_dispatcher)
.chain(file_dispatcher)
.apply()?;
Ok(())
}
/// (Windows) Allow the application to display logs to the terminal
/// regardless if it was compiled with `windows_subsystem = "windows"`.
///
/// This is excluded on non-Windows targets.
#[cfg(target_os = "windows")]
fn attach_windows_console() {
use win32console::console::WinConsole;
const ATTACH_PARENT_PROCESS: u32 = 0xFFFFFFFF;
let _ = WinConsole::attach_console(ATTACH_PARENT_PROCESS);
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn init_logger() {
match setup_logger() {
Ok(()) => (),
Err(error) => panic!("Error: {error}"),
}
}
}

776
crates/uad-gui/src/style.rs Normal file
View file

@ -0,0 +1,776 @@
#![allow(
non_snake_case,
clippy::trivially_copy_pass_by_ref,
clippy::wildcard_imports,
reason = "Iced style modules use PascalCase and &Theme; wildcard for local convenience"
)]
use crate::theme::{ColorPalette, Theme};
use iced::widget::{
button, checkbox, container, overlay, pick_list, radio, scrollable, text, text_editor,
text_input,
};
use iced::{Background, Border, Color, Shadow};
// Implement theming catalogs for our custom `Theme` so generic widgets
// like `Button<'_, Message, Theme, Renderer>` compile under iced 0.13.
impl button::Catalog for Theme {
type Class<'a> = button::StyleFn<'a, Theme>;
fn default<'a>() -> <Self as button::Catalog>::Class<'a> {
Box::new(|t: &Theme, s: button::Status| Button::Primary(t, s))
}
fn style(
&self,
class: &<Self as button::Catalog>::Class<'_>,
status: button::Status,
) -> button::Style {
(class)(self, status)
}
}
impl checkbox::Catalog for Theme {
type Class<'a> = checkbox::StyleFn<'a, Theme>;
fn default<'a>() -> <Self as checkbox::Catalog>::Class<'a> {
Box::new(|t: &Theme, s: checkbox::Status| CheckBox::SettingsEnabled(t, s))
}
fn style(
&self,
class: &<Self as checkbox::Catalog>::Class<'_>,
status: checkbox::Status,
) -> checkbox::Style {
(class)(self, status)
}
}
impl container::Catalog for Theme {
type Class<'a> = container::StyleFn<'a, Theme>;
fn default<'a>() -> <Self as container::Catalog>::Class<'a> {
Box::new(|t: &Theme| Container::Background(t))
}
fn style(&self, class: &<Self as container::Catalog>::Class<'_>) -> container::Style {
(class)(self)
}
}
impl scrollable::Catalog for Theme {
type Class<'a> = scrollable::StyleFn<'a, Theme>;
fn default<'a>() -> <Self as scrollable::Catalog>::Class<'a> {
Box::new(|t: &Theme, s: scrollable::Status| Scrollable::Description(t, s))
}
fn style(
&self,
class: &<Self as scrollable::Catalog>::Class<'_>,
status: scrollable::Status,
) -> scrollable::Style {
(class)(self, status)
}
}
impl text::Catalog for Theme {
type Class<'a> = text::StyleFn<'a, Theme>;
fn default<'a>() -> <Self as text::Catalog>::Class<'a> {
Box::new(|t: &Theme| Text::Default(t))
}
fn style(&self, class: &<Self as text::Catalog>::Class<'_>) -> text::Style {
(class)(self)
}
}
// Additional catalogs required by Iced 0.13 generic theming
impl text_input::Catalog for Theme {
type Class<'a> = text_input::StyleFn<'a, Theme>;
fn default<'a>() -> <Self as text_input::Catalog>::Class<'a> {
Box::new(|t: &Theme, s: text_input::Status| {
let p = t.palette();
let active = text_input::Style {
background: Background::Color(p.base.foreground),
border: Border {
color: p.base.foreground,
width: 0.0,
radius: 5.0.into(),
},
icon: Color {
a: 0.5,
..p.normal.primary
},
placeholder: p.normal.surface,
value: p.bright.primary,
selection: p.normal.primary,
};
let focused = text_input::Style {
background: Background::Color(p.base.foreground),
border: Border {
color: Color {
a: 0.5,
..p.normal.primary
},
width: 1.0,
radius: 2.0.into(),
},
icon: Color {
a: 0.5,
..p.normal.primary
},
placeholder: p.normal.surface,
value: p.bright.primary,
selection: p.normal.primary,
};
let disabled = text_input::Style {
background: Background::Color(p.base.background),
border: Border {
color: Color {
a: 0.5,
..p.base.foreground
},
width: 1.0,
radius: 2.0.into(),
},
icon: Color {
a: 0.5,
..p.base.foreground
},
placeholder: p.normal.surface,
value: p.bright.primary,
selection: p.normal.primary,
};
match s {
text_input::Status::Active => active,
text_input::Status::Focused { .. } | text_input::Status::Hovered => focused,
text_input::Status::Disabled => disabled,
}
})
}
fn style(
&self,
class: &<Self as text_input::Catalog>::Class<'_>,
status: text_input::Status,
) -> text_input::Style {
(class)(self, status)
}
}
impl pick_list::Catalog for Theme {
type Class<'a> = pick_list::StyleFn<'a, Theme>;
fn default<'a>() -> <Self as pick_list::Catalog>::Class<'a> {
Box::new(|t: &Theme, s: pick_list::Status| {
let p = t.palette();
let border_color = match s {
pick_list::Status::Hovered => p.normal.primary,
_ => Color {
a: 0.5,
..p.normal.primary
},
};
pick_list::Style {
text_color: p.bright.surface,
placeholder_color: p.bright.surface,
handle_color: p.bright.surface,
background: Background::Color(p.base.background),
border: Border {
color: border_color,
width: 1.0,
radius: 2.0.into(),
},
}
})
}
fn style(
&self,
class: &<Self as pick_list::Catalog>::Class<'_>,
status: pick_list::Status,
) -> pick_list::Style {
(class)(self, status)
}
}
impl overlay::menu::Catalog for Theme {
type Class<'a> = overlay::menu::StyleFn<'a, Theme>;
fn default<'a>() -> <Self as overlay::menu::Catalog>::Class<'a> {
Box::new(|t: &Theme| {
let p = t.palette();
overlay::menu::Style {
text_color: p.bright.surface,
background: p.base.background.into(),
border: Border {
color: p.base.background,
width: 1.0,
radius: 2.0.into(),
},
selected_text_color: p.bright.surface,
selected_background: p.normal.primary.into(),
shadow: Shadow::default(),
}
})
}
fn style(&self, class: &<Self as overlay::menu::Catalog>::Class<'_>) -> overlay::menu::Style {
(class)(self)
}
}
impl radio::Catalog for Theme {
type Class<'a> = radio::StyleFn<'a, Theme>;
fn default<'a>() -> <Self as radio::Catalog>::Class<'a> {
Box::new(|t: &Theme, s: radio::Status| {
let p = t.palette();
let active = radio::Style {
background: Color::TRANSPARENT.into(),
dot_color: p.bright.primary,
border_width: 1.0,
border_color: p.bright.primary,
text_color: None,
};
match s {
radio::Status::Active { .. } => active,
radio::Status::Hovered { .. } => radio::Style {
border_width: 2.0,
..active
},
}
})
}
fn style(
&self,
class: &<Self as radio::Catalog>::Class<'_>,
status: radio::Status,
) -> radio::Style {
(class)(self, status)
}
}
impl text_editor::Catalog for Theme {
type Class<'a> = text_editor::StyleFn<'a, Theme>;
fn default<'a>() -> <Self as text_editor::Catalog>::Class<'a> {
Box::new(|t: &Theme, _s: text_editor::Status| {
let p = t.palette();
text_editor::Style {
background: Background::Color(p.base.foreground),
border: Border {
color: Color::TRANSPARENT,
width: 0.0,
radius: 0.0.into(),
},
placeholder: p.normal.surface,
value: p.bright.surface,
selection: Color {
a: 0.3,
..p.normal.primary
},
}
})
}
fn style(
&self,
class: &<Self as text_editor::Catalog>::Class<'_>,
status: text_editor::Status,
) -> text_editor::Style {
(class)(self, status)
}
}
// Rule styling for custom Theme (needed by vertical_rule)
impl iced::widget::rule::Catalog for Theme {
type Class<'a> = iced::widget::rule::StyleFn<'a, Theme>;
fn default<'a>() -> <Self as iced::widget::rule::Catalog>::Class<'a> {
Box::new(|t: &Theme| {
let p = t.palette();
iced::widget::rule::Style {
color: p.bright.surface,
radius: 2.0.into(),
fill_mode: iced::widget::rule::FillMode::Full,
snap: true,
}
})
}
fn style(
&self,
class: &<Self as iced::widget::rule::Catalog>::Class<'_>,
) -> iced::widget::rule::Style {
(class)(self)
}
}
pub mod Container {
use super::*;
#[allow(dead_code, reason = "Used by other themes or future styles")]
#[must_use]
pub fn Invisible(_: &Theme) -> container::Style {
container::Style::default()
}
#[must_use]
pub fn Frame(theme: &Theme) -> container::Style {
let p = theme.palette();
container::Style {
background: Some(Background::Color(p.base.foreground)),
text_color: Some(p.bright.surface),
border: Border {
color: Color::TRANSPARENT,
width: 0.0,
radius: 5.0.into(),
},
shadow: Shadow::default(),
snap: true,
}
}
#[must_use]
pub fn BorderedFrame(theme: &Theme) -> container::Style {
let p = theme.palette();
container::Style {
background: Some(Background::Color(p.base.foreground)),
text_color: Some(p.bright.surface),
border: Border {
color: p.normal.error,
width: 1.0,
radius: 5.0.into(),
},
shadow: Shadow::default(),
snap: true,
}
}
#[allow(dead_code, reason = "Currently unused in some views")]
#[must_use]
pub fn Tooltip(theme: &Theme) -> container::Style {
let p = theme.palette();
container::Style {
background: Some(Background::Color(p.base.foreground)),
text_color: Some(p.bright.surface),
border: Border {
color: p.normal.primary,
width: 1.0,
radius: 8.0.into(),
},
shadow: Shadow::default(),
snap: true,
}
}
#[must_use]
pub fn Background(theme: &Theme) -> container::Style {
let p = theme.palette();
container::Style {
background: Some(Background::Color(p.base.background)),
text_color: Some(p.bright.surface),
border: Border {
color: Color::TRANSPARENT,
width: 0.0,
radius: 5.0.into(),
},
shadow: Shadow::default(),
snap: true,
}
}
}
pub mod Button {
use super::*;
#[allow(
dead_code,
reason = "Helper used by multiple styles; may be inlined by compiler"
)]
fn base(border_color: Color) -> button::Style {
button::Style {
background: None,
text_color: Color::WHITE,
border: Border {
color: border_color,
width: 1.0,
radius: 2.0.into(),
},
shadow: Shadow::default(),
snap: true,
}
}
#[must_use]
pub fn Primary(theme: &Theme, status: button::Status) -> button::Style {
let p = theme.palette();
let mut style = style_active_hover_disabled(p.bright.primary, p.bright.primary, status);
if matches!(status, button::Status::Active | button::Status::Pressed) {
style.background = Some(Background::Color(p.base.foreground));
}
style
}
#[allow(
dead_code,
reason = "Alias kept for semantic clarity in some call-sites"
)]
#[must_use]
pub fn SelfUpdate(theme: &Theme, status: button::Status) -> button::Style {
Primary(theme, status)
}
#[must_use]
pub fn RestorePackage(theme: &Theme, status: button::Status) -> button::Style {
let p = theme.palette();
let mut style = style_active_hover_disabled(p.bright.secondary, p.bright.secondary, status);
if matches!(status, button::Status::Active | button::Status::Pressed) {
style.background = Some(Background::Color(p.base.foreground));
}
if matches!(status, button::Status::Disabled) {
style.background = Some(Background::Color(Color {
a: 0.05,
..p.normal.primary
}));
style.text_color = p.bright.primary;
}
style
}
#[must_use]
pub fn UninstallPackage(theme: &Theme, status: button::Status) -> button::Style {
let p = theme.palette();
let mut style = style_active_hover_disabled(p.bright.error, p.bright.error, status);
if matches!(status, button::Status::Active | button::Status::Pressed) {
style.background = Some(Background::Color(p.base.foreground));
}
style
}
#[allow(
dead_code,
reason = "Style exposed for disabled state buttons in some contexts"
)]
#[must_use]
pub fn Unavailable(theme: &Theme, status: button::Status) -> button::Style {
UninstallPackage(theme, status)
}
#[must_use]
pub fn NormalPackage(theme: &Theme, status: button::Status) -> button::Style {
let p = theme.palette();
match status {
button::Status::Hovered => button::Style {
background: Some(Background::Color(Color {
a: 0.25,
..p.normal.primary
})),
text_color: p.bright.surface,
border: Border {
color: p.base.background,
width: 0.0,
radius: 5.0.into(),
},
shadow: Shadow::default(),
snap: true,
},
_ => button::Style {
background: Some(Background::Color(p.base.foreground)),
text_color: p.bright.surface,
border: Border {
color: p.base.background,
width: 0.0,
radius: 5.0.into(),
},
shadow: Shadow::default(),
snap: true,
},
}
}
#[must_use]
pub fn SelectedPackage(theme: &Theme, _status: button::Status) -> button::Style {
let p = theme.palette();
button::Style {
background: Some(Background::Color(Color {
a: 0.25,
..p.normal.primary
})),
text_color: p.bright.primary,
border: Border {
color: p.normal.primary,
width: 0.0,
radius: 5.0.into(),
},
shadow: Shadow::default(),
snap: true,
}
}
#[allow(dead_code, reason = "Used in views where buttons must be invisible")]
#[must_use]
pub fn Hidden(_: &Theme, _: button::Status) -> button::Style {
button::Style {
background: Some(Background::Color(Color::TRANSPARENT)),
text_color: Color::TRANSPARENT,
border: Border {
color: Color::TRANSPARENT,
width: 0.0,
radius: 5.0.into(),
},
shadow: Shadow::default(),
snap: true,
}
}
fn style_active_hover_disabled(
main: Color,
text: Color,
status: button::Status,
) -> button::Style {
match status {
button::Status::Active | button::Status::Pressed => button::Style {
background: Some(Background::Color(main)),
text_color: text,
border: Border {
color: Color { a: 0.5, ..main },
width: 1.0,
radius: 2.0.into(),
},
shadow: Shadow::default(),
snap: true,
},
button::Status::Hovered => button::Style {
background: Some(Background::Color(Color { a: 0.25, ..main })),
text_color: text,
border: Border {
color: Color { a: 0.5, ..main },
width: 1.0,
radius: 2.0.into(),
},
shadow: Shadow::default(),
snap: true,
},
button::Status::Disabled => button::Style {
background: Some(Background::Color(Color { a: 0.05, ..main })),
text_color: Color { a: 0.5, ..text },
border: Border {
color: Color { a: 0.5, ..main },
width: 1.0,
radius: 2.0.into(),
},
shadow: Shadow::default(),
snap: true,
},
}
}
}
pub mod Scrollable {
use super::*;
#[allow(dead_code, reason = "Kept for future custom rails variations")]
fn rails(scroller_color: Color) -> (scrollable::Rail, scrollable::Rail) {
let rail = scrollable::Rail {
background: Some(Background::Color(Color::TRANSPARENT)),
border: Border {
color: Color::TRANSPARENT,
width: 0.0,
radius: 5.0.into(),
},
scroller: scrollable::Scroller {
background: Background::Color(scroller_color),
border: Border {
color: Color::TRANSPARENT,
width: 1.0,
radius: 5.0.into(),
},
},
};
(rail, rail)
}
fn autoscroll(p: ColorPalette) -> scrollable::AutoScroll {
scrollable::AutoScroll {
background: Background::Color(Color {
a: 0.05,
..p.base.background
}),
border: Border {
color: Color::TRANSPARENT,
width: 0.0,
radius: 5.0.into(),
},
shadow: Shadow::default(),
icon: p.bright.surface,
}
}
#[must_use]
pub fn Description(theme: &Theme, _status: scrollable::Status) -> scrollable::Style {
let p = theme.palette();
let (v, h) = rails(p.normal.surface);
scrollable::Style {
container: container::Style::default(),
vertical_rail: v,
horizontal_rail: h,
gap: Some(Background::Color(Color::TRANSPARENT)),
auto_scroll: autoscroll(p),
}
}
#[must_use]
pub fn Packages(theme: &Theme, _status: scrollable::Status) -> scrollable::Style {
let p = theme.palette();
let (v, h) = rails(p.base.foreground);
scrollable::Style {
container: container::Style::default(),
vertical_rail: v,
horizontal_rail: h,
gap: Some(Background::Color(Color::TRANSPARENT)),
auto_scroll: autoscroll(p),
}
}
}
pub mod CheckBox {
use super::*;
#[must_use]
pub fn PackageEnabled(theme: &Theme, _status: checkbox::Status) -> checkbox::Style {
let p = theme.palette();
checkbox::Style {
background: Background::Color(p.base.background),
icon_color: p.bright.primary,
border: Border {
color: p.base.background,
width: 1.0,
radius: 5.0.into(),
},
text_color: Some(p.bright.surface),
}
}
#[must_use]
pub fn PackageDisabled(theme: &Theme, _status: checkbox::Status) -> checkbox::Style {
let p = theme.palette();
checkbox::Style {
background: Background::Color(Color {
a: 0.55,
..p.base.background
}),
icon_color: p.bright.primary,
border: Border {
color: p.normal.primary,
width: 1.0,
radius: 5.0.into(),
},
text_color: Some(p.normal.primary),
}
}
#[must_use]
pub fn SettingsEnabled(theme: &Theme, _status: checkbox::Status) -> checkbox::Style {
let p = theme.palette();
checkbox::Style {
background: Background::Color(p.base.background),
icon_color: p.bright.primary,
border: Border {
color: p.bright.primary,
width: 1.0,
radius: 5.0.into(),
},
text_color: Some(p.bright.surface),
}
}
#[must_use]
pub fn SettingsDisabled(theme: &Theme, _status: checkbox::Status) -> checkbox::Style {
let p = theme.palette();
checkbox::Style {
background: Background::Color(p.base.foreground),
icon_color: p.bright.primary,
border: Border {
color: p.normal.primary,
width: 1.0,
radius: 5.0.into(),
},
text_color: Some(p.bright.surface),
}
}
}
pub mod Text {
use super::*;
#[must_use]
pub fn Default(theme: &Theme) -> text::Style {
let _ = theme;
text::Style::default()
}
#[must_use]
pub fn Ok(theme: &Theme) -> text::Style {
let p = theme.palette();
text::Style {
color: Some(p.bright.secondary),
}
}
#[must_use]
pub fn Danger(theme: &Theme) -> text::Style {
let p = theme.palette();
text::Style {
color: Some(p.bright.error),
}
}
#[must_use]
pub fn Commentary(theme: &Theme) -> text::Style {
let p = theme.palette();
text::Style {
color: Some(p.normal.surface),
}
}
#[allow(
dead_code,
reason = "Convenience factory used by dynamic text coloring"
)]
pub fn Color(c: Color) -> impl Fn(&Theme) -> text::Style {
move |_t: &Theme| text::Style { color: Some(c) }
}
}
// Unit tests
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_palette() {
let palette = Theme::Dark.palette();
assert_ne!(palette.base.background, palette.base.foreground);
assert_ne!(palette.normal.primary, Color::BLACK);
assert_ne!(palette.normal.surface, Color::BLACK);
assert_ne!(palette.bright.primary, Color::BLACK);
// if `LIGHT` then this can be `BLACK`
// https://github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation/pull/730#issuecomment-2525405134
//assert_ne!(palette.bright.surface, Color::BLACK);
assert_ne!(palette.normal.error, Color::BLACK);
assert_ne!(palette.bright.error, Color::BLACK);
}
}

219
crates/uad-gui/src/theme.rs Normal file
View file

@ -0,0 +1,219 @@
use iced::theme::{self, Mode, Palette, Style};
use iced::{Color, color};
use std::sync::LazyLock;
/*
In-memory caching.
This fixes the perf bug
caused by Iced repeatedly calling `palette`.
Coincidentally, this also ensures consistent colors across the GUI,
at the cost of requiring a restart to update the palette.
(this is just a patch, not a fix)
*/
pub static OS_COLOR_SCHEME: LazyLock<dark_light::Mode> =
LazyLock::new(|| dark_light::detect().unwrap_or(dark_light::Mode::Unspecified));
#[derive(Default, Debug, PartialEq, Eq, Copy, Clone)]
/// Color scheme
pub enum Theme {
#[default]
/// `Dark` or `Light`, according to `dark_light`
Auto,
/// `Dark`-ish and purple
Lupin,
/// white on black
Dark,
/// black on white
Light,
}
#[derive(Debug, Clone, Copy)]
pub struct BaseColors {
pub background: Color,
pub foreground: Color,
}
#[derive(Debug, Clone, Copy)]
pub struct NormalColors {
pub primary: Color,
#[allow(dead_code, reason = "Reserved for future palette updates")]
pub secondary: Color,
pub surface: Color,
pub error: Color,
}
#[derive(Debug, Clone, Copy)]
pub struct BrightColors {
pub primary: Color,
pub secondary: Color,
pub surface: Color,
pub error: Color,
}
#[derive(Debug, Clone, Copy)]
pub struct ColorPalette {
pub base: BaseColors,
pub normal: NormalColors,
pub bright: BrightColors,
}
impl Theme {
pub const ALL: [Self; 4] = [Self::Auto, Self::Lupin, Self::Dark, Self::Light];
#[allow(
clippy::unreadable_literal,
reason = "https://github.com/Universal-Debloater-Alliance/universal-android-debloater-next-generation/pull/578#discussion_r1759653408"
)]
/// This `fn` _could_ be `const`,
/// but `deref`ing a lazy-`static` is non-`const`.
#[must_use]
pub fn palette(self) -> ColorPalette {
const DARK: ColorPalette = ColorPalette {
base: BaseColors {
background: color!(0x111111),
foreground: color!(0x1C1C1C),
},
normal: NormalColors {
primary: color!(0x5E4266),
secondary: color!(0x386E50),
surface: color!(0x828282),
error: color!(0x992B2B),
},
bright: BrightColors {
primary: color!(0xBA84FC),
secondary: color!(0x49EB7A),
surface: color!(0xE0E0E0),
error: color!(0xC13047),
},
};
const LIGHT: ColorPalette = ColorPalette {
base: BaseColors {
background: color!(0xEEEEEE),
foreground: color!(0xE0E0E0),
},
normal: NormalColors {
primary: color!(0x818181),
secondary: color!(0xF9D659),
surface: color!(0x818181),
error: color!(0x992B2B),
},
bright: BrightColors {
primary: color!(0x673AB7),
secondary: color!(0x3797A4),
surface: color!(0x000000),
error: color!(0xC13047),
},
};
const LUPIN: ColorPalette = ColorPalette {
base: BaseColors {
background: color!(0x282A36),
foreground: color!(0x353746),
},
normal: NormalColors {
primary: color!(0x58406F),
secondary: color!(0x386E50),
surface: color!(0xA2A4A3),
error: color!(0xA13034),
},
bright: BrightColors {
primary: color!(0xBD94F9),
secondary: color!(0x49EB7A),
surface: color!(0xF4F8F3),
error: color!(0xE63E6D),
},
};
match self {
Self::Dark => DARK,
Self::Light => LIGHT,
Self::Lupin => LUPIN,
Self::Auto => match *OS_COLOR_SCHEME {
dark_light::Mode::Light => LIGHT,
dark_light::Mode::Dark | dark_light::Mode::Unspecified => DARK,
},
}
}
}
impl std::fmt::Display for Theme {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}",
match self {
Self::Dark => "Dark",
Self::Light => "Light",
Self::Lupin => "Lupin",
Self::Auto => "Auto (follow system theme)",
}
)
}
}
/// Converts a string to the GUI's Theme type
#[must_use]
pub fn string_to_theme(theme: &str) -> Theme {
match theme {
"Lupin" => Theme::Lupin,
"Dark" => Theme::Dark,
"Light" => Theme::Light,
_ => Theme::Auto,
}
}
impl theme::Base for Theme {
fn default(preference: Mode) -> Self {
match preference {
Mode::Light => Self::Light,
Mode::Dark => Self::Dark,
Mode::None => match *OS_COLOR_SCHEME {
dark_light::Mode::Light => Self::Light,
dark_light::Mode::Dark | dark_light::Mode::Unspecified => Self::Dark,
},
}
}
fn mode(&self) -> Mode {
let resolved = match self {
Self::Auto => match *OS_COLOR_SCHEME {
dark_light::Mode::Light => Self::Light,
dark_light::Mode::Dark | dark_light::Mode::Unspecified => Self::Dark,
},
other => *other,
};
match resolved {
Self::Light => Mode::Light,
_ => Mode::Dark,
}
}
fn base(&self) -> Style {
let p = Self::palette(*self);
Style {
background_color: p.base.background,
text_color: p.bright.surface,
}
}
fn palette(&self) -> Option<Palette> {
let p = Self::palette(*self);
Some(Palette {
background: p.base.background,
text: p.bright.surface,
primary: p.normal.primary,
success: p.bright.secondary,
warning: p.normal.surface,
danger: p.normal.error,
})
}
fn name(&self) -> &str {
match self {
Self::Dark => "Dark",
Self::Light => "Light",
Self::Lupin => "Lupin",
Self::Auto => "Auto",
}
}
}

View file

@ -0,0 +1,174 @@
use crate::helpers::button_primary;
use crate::theme::Theme;
use crate::{gui::UpdateState, style, widgets::text};
use iced::widget::{Space, column, container, row};
use iced::{Alignment, Element, Length, Renderer};
use log::error;
use std::path::PathBuf;
use uad_core::CACHE_DIR;
use uad_core::adb;
use uad_core::uad_lists::LIST_FNAME;
use uad_core::utils::{FULL_NAME, NAME, last_modified_date, open_url};
#[cfg(feature = "self-update")]
use uad_core::update::SelfUpdateStatus;
#[derive(Default, Debug, Clone)]
pub struct About {}
#[derive(Debug, Clone)]
pub enum Message {
UrlPressed(PathBuf),
UpdateUadLists,
DoSelfUpdate,
}
impl About {
#[allow(
clippy::unused_self,
reason = "Trait-like shape required by GUI architecture"
)]
pub fn update(&mut self, msg: Message) {
if let Message::UrlPressed(url) = msg {
open_url(url);
}
// other events are handled by UadGui update()
}
#[allow(
clippy::unused_self,
reason = "Trait-like shape required by GUI architecture"
)]
pub fn view(&self, update_state: &UpdateState) -> Element<'_, Message, Theme, Renderer> {
let about_text = text(format!(
"{FULL_NAME} ({NAME}) is a free and open-source community project \naiming at simplifying the removal of pre-installed apps on any Android device."
));
let descr_container = container(about_text)
.width(Length::Fill)
.padding(25)
.style(style::Container::Frame);
let date = last_modified_date(CACHE_DIR.join(LIST_FNAME));
let uad_list_text =
text(format!("{NAME} package list: v{}", date.format("%Y%m%d"))).width(250);
let last_update_text = text(update_state.uad_list.to_string());
let uad_lists_btn = button_primary("Update").on_press(Message::UpdateUadLists);
#[cfg(feature = "self-update")]
let self_update_row = {
let self_update_btn = button_primary("Update").on_press(Message::DoSelfUpdate);
let uad_version_text =
text(format!("{NAME} version: v{}", env!("CARGO_PKG_VERSION"))).width(250);
let self_update_text = update_state
.self_update
.latest_release
.as_ref()
.map_or_else(
|| {
if update_state.self_update.status == SelfUpdateStatus::Done {
"(No update available)".to_string()
} else {
update_state.self_update.status.to_string()
}
},
|r| {
if update_state.self_update.status == SelfUpdateStatus::Updating {
update_state.self_update.status.to_string()
} else {
format!("({} available)", r.tag_name)
}
},
);
let last_self_update_text = text(self_update_text).style(style::Text::Default);
row![uad_version_text, self_update_btn, last_self_update_text,]
.align_y(Alignment::Center)
.spacing(10)
.width(550)
};
let uad_list_row = row![uad_list_text, uad_lists_btn, last_update_text,]
.align_y(Alignment::Center)
.spacing(10)
.width(550);
/*
There's no need to fetch this info every time the view is updated,
we could cache it in a `static` `LazyLock`.
But what if the system updates ADB while the app is running?
the numbers will be out of sync!
However, the server will still be the "old" version
until it's killed
*/
let adb_version_text = text(match adb::ACommand::new().version() {
Ok(s) => s
.lines()
.nth(0)
.unwrap_or_else(|| unreachable!())
// This allocation is good.
// If it was a ref, the app would hold the entire string
// instead of the relevant slice.
.to_string(),
Err(e) => {
error!("{e}");
"Couldn't fetch ADB version. Is it installed?".into()
// satisfy `match` by inferring the type of the `Ok` arm
}
})
.width(250);
let adb_version_row = row![adb_version_text].align_y(Alignment::Center).width(550);
#[cfg(feature = "self-update")]
let update_column = column![uad_list_row, self_update_row, adb_version_row];
#[cfg(not(feature = "self-update"))]
let update_column = column![uad_list_row, adb_version_row];
let update_column = update_column.align_x(Alignment::Center).spacing(10);
let update_container = container(update_column)
.width(Length::Fill)
.center_x(Length::Fill)
.padding(10)
.style(style::Container::Frame);
let website_btn =
button_primary("GitHub page").on_press(Message::UrlPressed(PathBuf::from(
"https://github.com/Universal-Debloater-Alliance/universal-android-debloater",
)));
let issue_btn = button_primary("Have an issue?")
.on_press(Message::UrlPressed(PathBuf::from(
"https://github.com/Universal-Debloater-Alliance/universal-android-debloater/issues",
)));
let log_btn = button_primary("Locate the logfiles")
.on_press(Message::UrlPressed(CACHE_DIR.to_path_buf()));
let wiki_btn = button_primary("Wiki").on_press(Message::UrlPressed(PathBuf::from(
"https://github.com/Universal-Debloater-Alliance/universal-android-debloater/wiki",
)));
let row = row![website_btn, wiki_btn, issue_btn, log_btn,].spacing(20);
let content = column![
Space::new().width(Length::Fill).height(Length::Shrink),
descr_container,
update_container,
row,
]
.width(Length::Fill)
.spacing(20)
.align_x(Alignment::Center);
container(content)
.width(Length::Fill)
.height(Length::Fill)
.padding(10)
.into()
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,694 @@
use crate::helpers::{button_primary, open_folder};
use crate::theme::Theme;
use crate::theme::string_to_theme;
use crate::{
style,
views::list::{List as AppsView, PackageInfo},
widgets::modal::Modal,
widgets::navigation_menu::ICONS,
widgets::package_row::PackageRow,
widgets::text,
};
use chrono;
use iced::widget::{Space, button, checkbox, column, container, pick_list, radio, row, scrollable};
use iced::{Alignment, Element, Length, Renderer, Task, alignment};
use log::{debug, error, info};
use std::path::PathBuf;
use uad_core::{
config::{BackupSettings, Config, DeviceSettings, GeneralSettings},
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_disabling, supports_multi_user,
},
utils::{DisplayablePath, Error, NAME, export_packages, generate_backup_name, open_url},
};
#[derive(Debug, Clone)]
pub enum PopUpModal {
ExportUninstalled,
}
#[derive(Debug, Clone)]
pub struct Settings {
pub general: GeneralSettings,
pub device: DeviceSettings,
is_loading: bool,
modal: Option<PopUpModal>,
}
impl Default for Settings {
fn default() -> Self {
Self {
general: Config::load_configuration_file().general,
device: DeviceSettings::default(),
is_loading: false,
modal: None,
}
}
}
#[derive(Debug, Clone)]
pub enum Message {
LoadDeviceSettings,
ExpertMode(bool),
DisableMode(bool),
MultiUserMode(bool),
ApplyTheme(Theme),
UrlPressed(PathBuf),
BackupSelected(DisplayablePath),
BackupDevice,
RestoreDevice,
RestoringDevice(Result<PackageInfo, AdbError>),
DeviceBackedUp(Result<bool, String>),
ChooseBackUpFolder,
FolderChosen(Result<PathBuf, Error>),
ExportPackages,
PackagesExported(Result<bool, String>),
ModalHide,
}
impl Settings {
pub fn update(
&mut self,
phone: &Phone,
packages: &[Vec<PackageRow>],
nb_running_async_adb_commands: &mut u32,
msg: Message,
selected_user: Option<User>,
) -> Task<Message> {
match msg {
Message::ModalHide => self.handle_modal_hide(),
Message::ExpertMode(toggled) => self.handle_expert_mode(phone, toggled),
Message::DisableMode(toggled) => self.handle_disable_mode(phone, toggled),
Message::MultiUserMode(toggled) => self.handle_multi_user_mode(phone, toggled),
Message::ApplyTheme(theme) => self.handle_apply_theme(phone, theme),
Message::UrlPressed(url) => Self::handle_url_pressed(url),
Message::LoadDeviceSettings => self.handle_load_device_settings(phone),
Message::BackupSelected(d_path) => self.handle_backup_selected(d_path),
Message::BackupDevice => self.handle_backup_device(phone, packages),
Message::DeviceBackedUp(result) => self.handle_device_backed_up(phone, result),
Message::RestoreDevice => {
self.handle_restore_device(phone, packages, nb_running_async_adb_commands)
}
Message::RestoringDevice(_) => Task::none(),
Message::FolderChosen(result) => self.handle_folder_chosen(phone, result),
Message::ChooseBackUpFolder => self.handle_choose_backup_folder(),
Message::ExportPackages => Self::handle_export_packages(selected_user, packages),
Message::PackagesExported(result) => self.handle_packages_exported(result),
}
}
fn handle_modal_hide(&mut self) -> Task<Message> {
self.modal = None;
Task::none()
}
fn handle_expert_mode(&mut self, _phone: &Phone, toggled: bool) -> Task<Message> {
self.general.expert_mode = toggled;
debug!("Config change: {self:?}");
let mut config = Config::load_configuration_file();
config.save_device_settings(self.device.clone(), self.general.clone());
Task::none()
}
fn handle_disable_mode(&mut self, phone: &Phone, toggled: bool) -> Task<Message> {
if supports_disabling(phone) {
self.device.disable_mode = toggled;
debug!("Config change: {self:?}");
let mut config = Config::load_configuration_file();
config.save_device_settings(self.device.clone(), self.general.clone());
}
Task::none()
}
fn handle_multi_user_mode(&mut self, _phone: &Phone, toggled: bool) -> Task<Message> {
self.device.multi_user_mode = toggled;
debug!("Config change: {self:?}");
let mut config = Config::load_configuration_file();
config.save_device_settings(self.device.clone(), self.general.clone());
Task::none()
}
fn handle_apply_theme(&mut self, _phone: &Phone, theme: Theme) -> Task<Message> {
self.general.theme = theme.to_string();
debug!("Config change: {self:?}");
let mut config = Config::load_configuration_file();
config.save_device_settings(self.device.clone(), self.general.clone());
Task::none()
}
fn handle_url_pressed(url: PathBuf) -> Task<Message> {
open_url(url);
Task::none()
}
fn handle_load_device_settings(&mut self, phone: &Phone) -> Task<Message> {
self.load_device_settings(phone);
Task::none()
}
fn load_device_settings(&mut self, phone: &Phone) {
let backups = list_available_backups(&self.general.backup_folder.join(&phone.adb_id));
let backup = BackupSettings {
backups: backups.clone(),
selected: backups.first().cloned(),
users: phone.user_list.clone(),
selected_user: phone.user_list.first().copied(),
backup_state: String::default(),
};
match Config::load_configuration_file()
.devices
.iter()
.find(|d| d.device_id == phone.adb_id)
{
Some(device) => {
self.device.clone_from(device);
self.device.backup = backup;
}
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),
backup,
};
}
}
}
fn handle_backup_selected(&mut self, d_path: DisplayablePath) -> Task<Message> {
self.device.backup.selected = Some(d_path.clone());
self.device.backup.users = list_available_backup_user(d_path);
Task::none()
}
fn handle_backup_device(
&mut self,
phone: &Phone,
packages: &[Vec<PackageRow>],
) -> Task<Message> {
let core_packages: Vec<Vec<_>> = packages
.iter()
.map(|user_packages| user_packages.iter().map(CorePackage::from).collect())
.collect();
// Avoid capturing &self and &phone in the future; clone owned data first.
let user_list = phone.user_list.clone();
let device_id = self.device.device_id.clone();
let packages_owned = core_packages;
Task::perform(
async move { backup_phone(user_list, device_id, &packages_owned) },
Message::DeviceBackedUp,
)
}
fn handle_device_backed_up(
&mut self,
phone: &Phone,
result: Result<bool, String>,
) -> Task<Message> {
match result {
Ok(_) => {
info!("[BACKUP] Backup successfully created");
self.device.backup.backups =
list_available_backups(&self.general.backup_folder.join(phone.adb_id.clone()));
self.device.backup.selected = self.device.backup.backups.first().cloned();
}
Err(err) => {
error!("[BACKUP FAILED] Backup creation failed: {err:?}");
}
}
Task::none()
}
fn handle_restore_device(
&mut self,
phone: &Phone,
packages: &[Vec<PackageRow>],
nb_running_async_adb_commands: &mut u32,
) -> Task<Message> {
let core_packages: Vec<Vec<_>> = packages
.iter()
.map(|user_packages| user_packages.iter().map(CorePackage::from).collect())
.collect();
match restore_backup(phone, &core_packages, &self.device) {
Ok(restore_result) => {
let mut commands = vec![];
*nb_running_async_adb_commands = 0;
for p in &restore_result.packages {
let p_info = PackageInfo {
i_user: p.i_user,
index: p.index,
removal: "RESTORE".to_string(),
before_cross_user_states: vec![],
};
for command in p.commands.clone() {
*nb_running_async_adb_commands += 1;
let p_info_clone = p_info.clone();
let phone_id = phone.adb_id.clone();
commands.push(Task::perform(
async move {
run_adb_shell_action(phone_id, command.as_str())
.map(|_| p_info_clone)
},
Message::RestoringDevice,
));
}
}
if restore_result.skipped_count > 0 {
self.device.backup.backup_state = format!(
"Restore completed with {} packages skipped (not found on device)",
restore_result.skipped_count
);
} else if restore_result.packages.is_empty() {
if get_android_sdk(&phone.adb_id) == 0 {
self.device.backup.backup_state = "Device is not connected".to_string();
} else {
self.device.backup.backup_state =
"Device state is already restored".to_string();
}
} else {
self.device.backup.backup_state = "Restore completed successfully".to_string();
}
info!(
"[RESTORE] Restoring backup {}",
self.device.backup.selected.as_ref().unwrap()
);
Task::batch(commands)
}
Err(e) => {
self.device.backup.backup_state.clone_from(&e);
error!("{} - {}", self.device.backup.selected.as_ref().unwrap(), e);
Task::none()
}
}
}
fn handle_folder_chosen(
&mut self,
phone: &Phone,
result: Result<PathBuf, Error>,
) -> Task<Message> {
self.is_loading = false;
if let Ok(path) = result {
self.general.backup_folder = path;
let mut config = Config::load_configuration_file();
config.save_device_settings(self.device.clone(), self.general.clone());
self.load_device_settings(phone);
}
Task::none()
}
fn handle_choose_backup_folder(&mut self) -> Task<Message> {
if self.is_loading {
Task::none()
} else {
self.is_loading = true;
Task::perform(open_folder(), Message::FolderChosen)
}
}
fn handle_export_packages(
selected_user: Option<User>,
packages: &[Vec<PackageRow>],
) -> Task<Message> {
let core_packages: Vec<Vec<_>> = packages
.iter()
.map(|user_packages| user_packages.iter().map(CorePackage::from).collect())
.collect();
Task::perform(
async move { export_packages(selected_user.unwrap_or_default(), &core_packages) },
Message::PackagesExported,
)
}
fn handle_packages_exported(&mut self, result: Result<bool, String>) -> Task<Message> {
match result {
Ok(_) => self.modal = Some(PopUpModal::ExportUninstalled),
Err(err) => error!("Failed to export list of uninstalled packages: {err:?}"),
}
Task::none()
}
pub fn view(
&self,
phone: &Phone,
apps_view: &AppsView,
) -> Element<'_, Message, Theme, Renderer> {
let content = if phone.adb_id.is_empty() {
self.build_no_device_content()
} else {
self.build_device_content(phone, apps_view)
};
if let Some(PopUpModal::ExportUninstalled) = self.modal {
return Self::render_export_modal(content);
}
container(scrollable(content))
.padding(10)
.width(Length::Fill)
.height(Length::Fill)
.into()
}
fn build_no_device_content(&self) -> Element<'_, Message, Theme, Renderer> {
column![
text("Theme").size(26),
self.theme_container(),
text("General").size(26),
self.general_container(),
text("Current device").size(26),
Self::no_device_container(),
text("Backup / Restore").size(26),
Self::no_device_container(),
]
.width(Length::Fill)
.spacing(20)
.into()
}
fn build_device_content(
&self,
phone: &Phone,
apps_view: &AppsView,
) -> Element<'_, Message, Theme, Renderer> {
column![
text("Theme").size(26),
self.theme_container(),
text("General").size(26),
self.general_container(),
text("Current device").size(26),
Self::warning_container(phone),
self.device_specific_container(phone),
text("Backup / Restore").size(26),
self.backup_restore_container(phone, apps_view),
]
.width(Length::Fill)
.spacing(20)
.into()
}
fn theme_container(&self) -> Element<'_, Message, Theme, Renderer> {
let radio_btn_theme = Theme::ALL
.iter()
.fold(row![].spacing(10), |column, option| {
column.push(
radio(
format!("{}", option.clone()),
*option,
Some(string_to_theme(&self.general.theme)),
Message::ApplyTheme,
)
.size(24),
)
});
container(radio_btn_theme)
.padding(10)
.width(Length::Fill)
.height(Length::Shrink)
.style(style::Container::Frame)
.into()
}
fn general_container(&self) -> Element<'_, Message, Theme, Renderer> {
let expert_mode_checkbox = checkbox(self.general.expert_mode)
.label("Allow to uninstall packages marked as \"unsafe\" (I KNOW WHAT I AM DOING)")
.on_toggle(Message::ExpertMode)
.size(20)
.style(style::CheckBox::SettingsEnabled);
let expert_mode_descr =
text("Most unsafe packages are known to bootloop the device if removed.")
.style(style::Text::Commentary);
let choose_backup_descr = text("Note: If you have previous backups, you will need to transfer them manually to newly changed backup folder to be able to use Restore functionality")
.style(style::Text::Commentary);
let choose_backup_btn = button(text("\u{E930}").font(ICONS))
.padding([5, 10])
.on_press(Message::ChooseBackUpFolder)
.style(style::Button::Primary);
let choose_backup_row = row![
choose_backup_btn,
"Choose backup folder",
Space::new().width(Length::Fill).height(Length::Shrink),
"Current folder: ",
text(self.general.backup_folder.to_string_lossy())
]
.spacing(10)
.align_y(Alignment::Center);
container(
column![
expert_mode_checkbox,
expert_mode_descr,
choose_backup_row,
choose_backup_descr,
]
.spacing(10),
)
.padding(10)
.width(Length::Fill)
.height(Length::Shrink)
.style(style::Container::Frame)
.into()
}
fn warning_container(phone: &Phone) -> Element<'static, Message, Theme, Renderer> {
container(
row![
text("The following settings only affect the currently selected device:")
.style(style::Text::Danger),
text(phone.model.clone()),
Space::new().width(Length::Fill).height(Length::Shrink),
text(phone.adb_id.clone()).style(style::Text::Commentary)
]
.spacing(7),
)
.padding(10)
.width(Length::Fill)
.style(style::Container::BorderedFrame)
.into()
}
fn device_specific_container(&self, phone: &Phone) -> Element<'_, Message, Theme, Renderer> {
let multi_user_mode_descr = row![
text("This will not affect the following protected work profile users: ")
.style(style::Text::Commentary),
text(
phone
.user_list
.iter()
.filter(|&u| u.protected)
.map(|u| u.id.to_string())
.collect::<Vec<String>>()
.join(", ")
)
.style(style::Text::Danger)
];
let multi_user_mode_checkbox = checkbox(self.device.multi_user_mode)
.label("Affect all the users of the device (not only the selected user)")
.on_toggle(Message::MultiUserMode)
.size(20)
.style(style::CheckBox::SettingsEnabled);
let disable_checkbox_style = if supports_disabling(phone) {
style::CheckBox::SettingsEnabled
} else {
style::CheckBox::SettingsDisabled
};
let disable_mode_descr =
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))
.on_press(Message::UrlPressed(PathBuf::from(
"https://github.com/Universal-Debloater-Alliance/universal-android-debloater/wiki/FAQ#\
why-is-the-disable-mode-setting-not-available-for-my-device",
)))
.height(22)
.style(style::Button::Unavailable);
let disable_mode_checkbox = checkbox(self.device.disable_mode)
.label("Clear and disable packages instead of uninstalling them")
.on_toggle(Message::DisableMode)
.size(20)
.style(disable_checkbox_style);
let disable_setting_row = if supports_disabling(phone) {
row![
disable_mode_checkbox,
Space::new().width(Length::Fill).height(Length::Shrink),
]
.width(Length::Fill)
} else {
row![
disable_mode_checkbox,
Space::new().width(Length::Fill).height(Length::Shrink),
unavailable_btn,
]
.width(Length::Fill)
};
container(
column![
multi_user_mode_checkbox,
multi_user_mode_descr,
disable_setting_row,
disable_mode_descr,
]
.spacing(10),
)
.padding(10)
.width(Length::Fill)
.height(Length::Shrink)
.style(style::Container::Frame)
.into()
}
fn backup_restore_container(
&self,
phone: &Phone,
apps_view: &AppsView,
) -> Element<'_, Message, Theme, Renderer> {
let backup_pick_list = pick_list(
self.device.backup.backups.clone(),
self.device.backup.selected.clone(),
Message::BackupSelected,
)
.padding(6);
let backup_btn = button_primary(text("Backup").align_x(alignment::Horizontal::Center))
.on_press(Message::BackupDevice)
.width(77);
let restore_btn = |enabled| {
if enabled {
button(text("Restore").align_x(alignment::Horizontal::Center))
.padding([5, 10])
.on_press(Message::RestoreDevice)
.width(77)
} else {
button(
text("No backup")
.align_x(alignment::Horizontal::Center)
.align_y(alignment::Vertical::Center),
)
.padding([5, 10])
.width(77)
}
};
let locate_backup_btn = if self.device.backup.backups.is_empty() {
button_primary("Open backup directory")
} else {
button_primary("Open backup directory").on_press(Message::UrlPressed(
self.general.backup_folder.join(phone.adb_id.clone()),
))
};
let export_btn = button_primary("Export").on_press(Message::ExportPackages);
let backup_row = row![
backup_btn,
"Backup the current state of the phone",
Space::new().width(Length::Fill).height(Length::Shrink),
locate_backup_btn,
]
.spacing(10)
.align_y(Alignment::Center);
let restore_row = if self.device.backup.backups.is_empty() {
row![]
} else {
row![
restore_btn(true),
"Restore the state of the device",
Space::new().width(Length::Fill).height(Length::Shrink),
text(self.device.backup.backup_state.clone()).style(style::Text::Danger),
backup_pick_list,
]
.spacing(10)
.align_y(Alignment::Center)
};
let export_row = row![
export_btn,
"Export uninstalled packages with their description",
Space::new().width(Length::Fill).height(Length::Shrink),
text(format!(
"Selected: user {}",
apps_view.selected_user.unwrap_or_default().id
)),
]
.spacing(10)
.align_y(Alignment::Center);
container(column![backup_row, restore_row, export_row].spacing(10))
.padding(10)
.width(Length::Fill)
.height(Length::Shrink)
.style(style::Container::Frame)
.into()
}
fn no_device_container() -> Element<'static, Message, Theme, Renderer> {
container(text("No device detected").style(style::Text::Danger))
.padding(10)
.width(Length::Fill)
.style(style::Container::BorderedFrame)
.into()
}
fn render_export_modal<'a>(
content: Element<'a, Message, Theme, Renderer>,
) -> Element<'a, Message, Theme, Renderer> {
let title = container(row![text("Success").size(24)].align_y(Alignment::Center))
.width(Length::Fill)
.style(style::Container::Frame)
.padding([10, 0])
.center_y(Length::Shrink)
.center_x(Length::Shrink);
let text_box = row![
text(format!(
"Exported uninstalled packages into file.\nFile is exported in same directory where {NAME} is located."
))
.width(Length::Fill),
]
.padding(20);
let file_row =
row![text(generate_backup_name(chrono::Local::now())).style(style::Text::Commentary)]
.padding(20);
let modal_btn_row = row![
Space::new().width(Length::Fill).height(Length::Shrink),
button(text("Close").width(Length::Shrink))
.width(Length::Shrink)
.on_press(Message::ModalHide),
Space::new().width(Length::Fill).height(Length::Shrink),
];
let ctn = container(column![title, text_box, file_row, modal_btn_row])
.height(Length::Shrink)
.width(500)
.padding(10)
.style(style::Container::Frame);
let padded_content: Element<'a, Message, Theme, Renderer> =
container(content).padding(10).into();
Modal::new(padded_content, ctn)
.on_blur(Message::ModalHide)
.into()
}
}

View file

@ -1,3 +1,6 @@
pub mod modal;
pub mod navigation_menu;
pub mod package_row;
mod text;
pub use text::text;

View file

@ -1,22 +1,20 @@
use iced_native::alignment::Alignment;
use iced_native::widget::{self, Tree};
use iced_native::{
event, layout, mouse, overlay, renderer, Clipboard, Color, Element, Event, Layout, Length,
Point, Rectangle, Shell, Size, Widget,
};
use iced::advanced::widget::{self, Tree, Widget};
use iced::advanced::{Clipboard, Layout, Shell, layout, overlay, renderer};
use iced::mouse::{self, Cursor};
use iced::{Alignment, Color, Element, Event, Length, Point, Rectangle, Size, Vector, advanced};
/// A widget that centers a modal element over some base element
pub struct Modal<'a, Message, Renderer> {
base: Element<'a, Message, Renderer>,
modal: Element<'a, Message, Renderer>,
pub struct Modal<'a, Message, Theme, Renderer> {
base: Element<'a, Message, Theme, Renderer>,
modal: Element<'a, Message, Theme, Renderer>,
on_blur: Option<Message>,
}
impl<'a, Message, Renderer> Modal<'a, Message, Renderer> {
impl<'a, Message, Theme, Renderer> Modal<'a, Message, Theme, Renderer> {
/// Returns a new [`Modal`]
pub fn new(
base: impl Into<Element<'a, Message, Renderer>>,
modal: impl Into<Element<'a, Message, Renderer>>,
base: impl Into<Element<'a, Message, Theme, Renderer>>,
modal: impl Into<Element<'a, Message, Theme, Renderer>>,
) -> Self {
Self {
base: base.into(),
@ -25,9 +23,9 @@ impl<'a, Message, Renderer> Modal<'a, Message, Renderer> {
}
}
#[allow(clippy::missing_const_for_fn)]
/// Sets the message that will be produces when the background
/// of the [`Modal`] is pressed
#[must_use]
pub fn on_blur(self, on_blur: Message) -> Self {
Self {
on_blur: Some(on_blur),
@ -36,42 +34,47 @@ impl<'a, Message, Renderer> Modal<'a, Message, Renderer> {
}
}
impl<'a, Message, Renderer> Widget<Message, Renderer> for Modal<'a, Message, Renderer>
impl<Message, Theme, Renderer> Widget<Message, Theme, Renderer>
for Modal<'_, Message, Theme, Renderer>
where
Renderer: iced_native::Renderer,
Renderer: advanced::Renderer,
Message: Clone,
{
fn children(&self) -> Vec<Tree> {
vec![Tree::new(&self.base), Tree::new(&self.modal)]
}
fn size(&self) -> Size<Length> {
self.base.as_widget().size()
}
fn diff(&self, tree: &mut Tree) {
tree.diff_children(&[&self.base, &self.modal]);
}
fn width(&self) -> Length {
self.base.as_widget().width()
fn layout(
&mut self,
tree: &mut Tree,
renderer: &Renderer,
limits: &layout::Limits,
) -> layout::Node {
self.base
.as_widget_mut()
.layout(&mut tree.children[0], renderer, limits)
}
fn height(&self) -> Length {
self.base.as_widget().height()
}
fn layout(&self, renderer: &Renderer, limits: &layout::Limits) -> layout::Node {
self.base.as_widget().layout(renderer, limits)
}
fn on_event(
fn update(
&mut self,
state: &mut Tree,
event: Event,
event: &Event,
layout: Layout<'_>,
cursor_position: Point,
cursor_position: Cursor,
renderer: &Renderer,
clipboard: &mut dyn Clipboard,
shell: &mut Shell<'_, Message>,
) -> event::Status {
self.base.as_widget_mut().on_event(
viewport: &Rectangle,
) {
self.base.as_widget_mut().update(
&mut state.children[0],
event,
layout,
@ -79,17 +82,18 @@ where
renderer,
clipboard,
shell,
)
viewport,
);
}
fn draw(
&self,
state: &Tree,
renderer: &mut Renderer,
theme: &<Renderer as iced_native::Renderer>::Theme,
theme: &Theme,
style: &renderer::Style,
layout: Layout<'_>,
cursor_position: Point,
cursor: Cursor,
viewport: &Rectangle,
) {
self.base.as_widget().draw(
@ -98,7 +102,7 @@ where
theme,
style,
layout,
cursor_position,
cursor,
viewport,
);
}
@ -106,123 +110,131 @@ where
fn overlay<'b>(
&'b mut self,
state: &'b mut Tree,
layout: Layout<'_>,
layout: Layout<'b>,
_renderer: &Renderer,
) -> Option<overlay::Element<'b, Message, Renderer>> {
Some(overlay::Element::new(
layout.position(),
Box::new(Overlay {
content: &mut self.modal,
tree: &mut state.children[1],
size: layout.bounds().size(),
on_blur: self.on_blur.clone(),
}),
))
viewport: &Rectangle,
_translation: Vector,
) -> Option<overlay::Element<'b, Message, Theme, Renderer>> {
Some(overlay::Element::new(Box::new(Overlay {
position: layout.position(),
content: &mut self.modal,
tree: &mut state.children[1],
size: layout.bounds().size(),
on_blur: self.on_blur.clone(),
viewport: *viewport,
})))
}
fn mouse_interaction(
&self,
state: &Tree,
layout: Layout<'_>,
cursor_position: Point,
cursor: Cursor,
viewport: &Rectangle,
renderer: &Renderer,
) -> mouse::Interaction {
self.base.as_widget().mouse_interaction(
&state.children[0],
layout,
cursor_position,
cursor,
viewport,
renderer,
)
}
fn operate(
&self,
&mut self,
state: &mut Tree,
layout: Layout<'_>,
renderer: &Renderer,
operation: &mut dyn widget::Operation<Message>,
operation: &mut dyn widget::Operation,
) {
self.base
.as_widget()
.as_widget_mut()
.operate(&mut state.children[0], layout, renderer, operation);
}
}
struct Overlay<'a, 'b, Message, Renderer> {
content: &'b mut Element<'a, Message, Renderer>,
struct Overlay<'a, 'b, Message, Theme, Renderer> {
position: Point,
content: &'b mut Element<'a, Message, Theme, Renderer>,
tree: &'b mut Tree,
size: Size,
on_blur: Option<Message>,
viewport: Rectangle,
}
impl<'a, 'b, Message, Renderer> overlay::Overlay<Message, Renderer>
for Overlay<'a, 'b, Message, Renderer>
impl<Message, Theme, Renderer> overlay::Overlay<Message, Theme, Renderer>
for Overlay<'_, '_, Message, Theme, Renderer>
where
Renderer: iced_native::Renderer,
Renderer: advanced::Renderer,
Message: Clone,
{
fn layout(&self, renderer: &Renderer, _bounds: Size, position: Point) -> layout::Node {
fn layout(&mut self, renderer: &Renderer, _bounds: Size) -> layout::Node {
let limits = layout::Limits::new(Size::ZERO, self.size)
.width(Length::Fill)
.height(Length::Fill);
let mut child = self.content.as_widget().layout(renderer, &limits);
child.align(Alignment::Center, Alignment::Center, limits.max());
let child = self
.content
.as_widget_mut()
.layout(self.tree, renderer, &limits)
.align(Alignment::Center, Alignment::Center, limits.max());
let mut node = layout::Node::with_children(self.size, vec![child]);
node.move_to(position);
node
layout::Node::with_children(self.size, vec![child]).move_to(self.position)
}
fn on_event(
fn update(
&mut self,
event: Event,
event: &Event,
layout: Layout<'_>,
cursor_position: Point,
cursor: Cursor,
renderer: &Renderer,
clipboard: &mut dyn Clipboard,
shell: &mut Shell<'_, Message>,
) -> event::Status {
let content_bounds = layout.children().next().unwrap().bounds();
#[allow(clippy::equatable_if_let)]
if let Some(message) = self.on_blur.as_ref() {
if let Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) = &event {
if !content_bounds.contains(cursor_position) {
shell.publish(message.clone());
return event::Status::Captured;
}
) {
if let Some(message) = self.on_blur.as_ref()
&& matches!(
event,
Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left))
)
&& let Some(cursor_position) = cursor.position()
{
let content_bounds = layout
.children()
.next()
.expect("Layout must have at least 1 child")
.bounds();
if !content_bounds.contains(cursor_position) {
shell.publish(message.clone());
return;
}
}
self.content.as_widget_mut().on_event(
self.content.as_widget_mut().update(
self.tree,
event,
layout.children().next().unwrap(),
cursor_position,
cursor,
renderer,
clipboard,
shell,
)
&self.viewport,
);
}
fn draw(
&self,
renderer: &mut Renderer,
theme: &Renderer::Theme,
theme: &Theme,
style: &renderer::Style,
layout: Layout<'_>,
cursor_position: Point,
cursor: Cursor,
) {
renderer.fill_quad(
renderer::Quad {
bounds: layout.bounds(),
border_radius: renderer::BorderRadius::from(0.0),
border_width: 0.0,
border_color: Color::TRANSPARENT,
..renderer::Quad::default()
},
Color {
a: 0.80,
@ -236,7 +248,7 @@ where
theme,
style,
layout.children().next().unwrap(),
cursor_position,
cursor,
&layout.bounds(),
);
}
@ -245,9 +257,9 @@ where
&mut self,
layout: Layout<'_>,
renderer: &Renderer,
operation: &mut dyn widget::Operation<Message>,
operation: &mut dyn widget::Operation,
) {
self.content.as_widget().operate(
self.content.as_widget_mut().operate(
self.tree,
layout.children().next().unwrap(),
renderer,
@ -258,26 +270,27 @@ where
fn mouse_interaction(
&self,
layout: Layout<'_>,
cursor_position: Point,
viewport: &Rectangle,
cursor: Cursor,
renderer: &Renderer,
) -> mouse::Interaction {
self.content.as_widget().mouse_interaction(
self.tree,
layout.children().next().unwrap(),
cursor_position,
viewport,
cursor,
&self.viewport,
renderer,
)
}
}
impl<'a, Message, Renderer> From<Modal<'a, Message, Renderer>> for Element<'a, Message, Renderer>
impl<'a, Message, Theme, Renderer> From<Modal<'a, Message, Theme, Renderer>>
for Element<'a, Message, Theme, Renderer>
where
Renderer: 'a + iced_native::Renderer,
Theme: 'a,
Renderer: 'a + advanced::Renderer,
Message: 'a + Clone,
{
fn from(modal: Modal<'a, Message, Renderer>) -> Self {
fn from(modal: Modal<'a, Message, Theme, Renderer>) -> Self {
Element::new(modal)
}
}

View file

@ -0,0 +1,141 @@
use crate::helpers::button_primary;
use crate::theme::Theme;
pub use crate::views::about::Message as AboutMessage;
pub use crate::views::list::{List as AppsView, LoadingState as ListLoadingState};
use crate::{gui::Message, style, widgets::text};
use iced::widget::{Space, button, container, pick_list, row, tooltip};
use iced::{Alignment, Element, Font, Length, Renderer, alignment, font};
pub use uad_core::sync::Phone;
use uad_core::update::{SelfUpdateState, SelfUpdateStatus};
/// resources/assets/icons.ttf, loaded in [`crate::gui::UadGui`]
pub const ICONS: Font = Font {
family: font::Family::Name("icomoon"),
..Font::DEFAULT
};
#[allow(
clippy::too_many_lines,
reason = "Navigation layout composes many widgets inline"
)]
pub fn nav_menu<'a>(
device_list: &'a [Phone],
selected_device: Option<Phone>,
apps_view: &AppsView,
self_update_state: &SelfUpdateState,
) -> Element<'a, Message, Theme, Renderer> {
let apps_refresh_btn = button_primary(
text("\u{E900}")
.font(ICONS)
.width(22)
.align_x(alignment::Horizontal::Center),
)
.on_press(Message::RefreshButtonPressed);
let apps_refresh_tooltip = tooltip(
apps_refresh_btn,
"Refresh apps (Ctrl+Shift+5)",
tooltip::Position::Bottom,
)
.style(style::Container::Tooltip)
.gap(4);
let reboot_btn = button_primary("Reboot").on_press(Message::RebootButtonPressed);
let reboot_btn = tooltip(
reboot_btn,
"Reboot device (Ctrl+Shift+R)",
tooltip::Position::Bottom,
)
.style(style::Container::Tooltip)
.gap(4);
let uad_version_text = if let Some(r) = &self_update_state.latest_release {
match self_update_state.status {
SelfUpdateStatus::Failed => text(format!("Failed to update to {}", r.tag_name)),
SelfUpdateStatus::Checking => text(SelfUpdateStatus::Checking.to_string()),
SelfUpdateStatus::Done => text(format!(
"Update available: {} -> {}",
env!("CARGO_PKG_VERSION"),
r.tag_name
)),
SelfUpdateStatus::Updating => text("Updating please wait..."),
}
} else {
text(format!("v{}", env!("CARGO_PKG_VERSION")))
};
let update_btn = if self_update_state.latest_release.is_some() {
button("Update")
.on_press(Message::AboutAction(AboutMessage::DoSelfUpdate))
.padding([5, 10])
.style(style::Button::SelfUpdate)
} else {
button("").height(0).width(0).style(style::Button::Hidden)
};
let apps_btn = button_primary("Apps").on_press(Message::AppsPress);
let apps_btn = tooltip(apps_btn, "(Ctrl+Shift+A)", tooltip::Position::Bottom)
.style(style::Container::Tooltip)
.gap(4);
let about_btn = button_primary("About").on_press(Message::AboutPressed);
let about_btn = tooltip(about_btn, "(Ctrl+Shift+I)", tooltip::Position::Bottom)
.style(style::Container::Tooltip)
.gap(4);
let settings_btn = button_primary(
text("\u{E994}")
.font(ICONS)
.width(22)
.align_x(alignment::Horizontal::Center),
)
.on_press(Message::SettingsPressed);
let settings_btn = tooltip(settings_btn, "(Ctrl+Shift+S)", tooltip::Position::Bottom)
.style(style::Container::Tooltip)
.gap(4);
let device_list_text = match apps_view.loading_state {
ListLoadingState::FindingPhones => text("Finding connected devices..."),
_ => text("No devices/emulators found"),
};
let row = match selected_device {
Some(phone) => row![
reboot_btn,
apps_refresh_tooltip,
pick_list(device_list, Some(phone), Message::DeviceSelected,),
Space::new().width(Length::Fill).height(Length::Shrink),
uad_version_text,
update_btn,
apps_btn,
about_btn,
settings_btn,
]
.width(Length::Fill)
.align_y(Alignment::Center)
.spacing(10),
None => row![
reboot_btn,
apps_refresh_tooltip,
device_list_text,
Space::new().width(Length::Fill).height(Length::Shrink),
uad_version_text,
update_btn,
apps_btn,
about_btn,
settings_btn,
]
.width(Length::Fill)
.align_y(Alignment::Center)
.spacing(10),
};
container(row)
.width(Length::Fill)
.padding(10)
.style(style::Container::Frame)
.into()
}

View file

@ -1,19 +1,21 @@
use crate::core::sync::Phone;
use crate::core::theme::Theme;
use crate::core::uad_lists::{PackageState, Removal, UadList};
use crate::gui::style;
use crate::gui::views::settings::Settings;
use crate::style;
use crate::theme::Theme;
use crate::views::settings::Settings;
use crate::widgets::text;
use log::warn;
use uad_core::sync::{CorePackage, Phone};
use uad_core::uad_lists::{PackageState, Removal, UadList};
use iced::widget::{button, checkbox, row, text, Space};
use iced::{alignment, Alignment, Command, Element, Length, Renderer};
use iced::widget::{Space, button, checkbox, row};
use iced::{Alignment, Element, Length, Renderer, Task, alignment};
#[derive(Clone, Debug)]
pub struct PackageRow {
pub name: String,
pub state: PackageState,
pub description: String,
pub uad_list: UadList,
pub removal: Removal,
pub state: PackageState,
pub list: UadList,
pub selected: bool,
pub current: bool,
}
@ -26,34 +28,43 @@ pub enum Message {
}
impl PackageRow {
#[must_use]
pub fn new(
name: &str,
state: PackageState,
description: &str,
uad_list: UadList,
removal: Removal,
state: PackageState,
list: UadList,
selected: bool,
current: bool,
) -> Self {
Self {
name: name.to_string(),
state,
description: description.to_string(),
uad_list,
removal,
state,
list,
selected,
current,
}
}
pub fn update(&mut self, _message: &Message) -> Command<Message> {
Command::none()
#[allow(
clippy::unused_self,
reason = "Consistent component API; may change later"
)]
pub fn update(&mut self, _message: &Message) -> Task<Message> {
Task::none()
}
pub fn view(&self, settings: &Settings, _phone: &Phone) -> Element<Message, Renderer<Theme>> {
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;
let button_style: fn(&Theme, iced::widget::button::Status) -> iced::widget::button::Style;
let action_text;
let action_btn;
let selection_checkbox;
@ -86,22 +97,26 @@ impl PackageRow {
|| self.state != PackageState::Enabled
|| settings.general.expert_mode
{
selection_checkbox = checkbox("", self.selected, Message::ToggleSelection)
selection_checkbox = checkbox(self.selected)
.on_toggle(Message::ToggleSelection)
.size(20)
.style(style::CheckBox::PackageEnabled);
action_btn = button(
text(action_text)
.horizontal_alignment(alignment::Horizontal::Center)
.align_x(alignment::Horizontal::Center)
.width(100),
)
.on_press(Message::ActionPressed);
} else {
selection_checkbox = checkbox("", self.selected, Message::ToggleSelection)
selection_checkbox = checkbox(self.selected)
.on_toggle(Message::ToggleSelection)
.size(20)
.style(style::CheckBox::PackageDisabled);
action_btn = button(
text(action_text)
.horizontal_alignment(alignment::Horizontal::Center)
.align_x(alignment::Horizontal::Center)
.width(100),
);
}
@ -113,7 +128,8 @@ impl PackageRow {
text(&self.name).width(Length::FillPortion(8)),
action_btn.style(button_style)
]
.align_items(Alignment::Center)
.spacing(8)
.align_y(Alignment::Center)
)
.padding(8)
.style(if self.current {
@ -123,9 +139,62 @@ impl PackageRow {
})
.width(Length::Fill)
.on_press(Message::PackagePressed),
Space::with_width(15)
Space::new().width(Length::Fixed(15.0))
]
.align_items(Alignment::Center)
.align_y(Alignment::Center)
.into()
}
}
// Conversions between PackageRow and CorePackage
impl From<CorePackage> for PackageRow {
fn from(core: CorePackage) -> Self {
Self {
name: core.name.clone(),
description: core.description,
removal: core.removal,
state: core.state,
list: core.list,
selected: false, // Default to not selected
current: false, // Default to not current
}
}
}
impl From<&CorePackage> for PackageRow {
fn from(core: &CorePackage) -> Self {
Self {
name: core.name.clone(),
description: core.description.clone(),
removal: core.removal,
state: core.state,
list: core.list,
selected: false,
current: false,
}
}
}
impl From<&PackageRow> for CorePackage {
fn from(row: &PackageRow) -> Self {
Self {
name: row.name.clone(),
description: row.description.clone(),
removal: row.removal,
state: row.state,
list: row.list,
}
}
}
impl From<PackageRow> for CorePackage {
fn from(row: PackageRow) -> Self {
Self {
name: row.name,
description: row.description,
removal: row.removal,
state: row.state,
list: row.list,
}
}
}

View file

@ -0,0 +1,13 @@
#![allow(
clippy::disallowed_types,
reason = "this is the replacement that enforces advanced shaping for disallowed [`iced::widget::Text`]"
)]
use crate::theme::Theme;
use iced::advanced::text::IntoFragment;
use iced::widget;
// Creates a new Text widget with advanced shaping.
pub fn text<'a>(text: impl IntoFragment<'a>) -> widget::Text<'a, Theme> {
widget::Text::new(text).shaping(iced::widget::text::Shaping::Advanced)
}

27
flake.lock generated Normal file
View file

@ -0,0 +1,27 @@
{
"nodes": {
"nixpkgs": {
"locked": {
"lastModified": 1776949667,
"narHash": "sha256-GMSVw35Q+294GlrTUKlx087E31z7KurReQ1YHSKp5iw=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "01fbdeef22b76df85ea168fbfe1bfd9e63681b30",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"nixpkgs": "nixpkgs"
}
}
},
"root": "root",
"version": 7
}

69
flake.nix Normal file
View file

@ -0,0 +1,69 @@
{
description = "devshell for uad-ng";
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
outputs =
{ nixpkgs, ... }:
let
forSystems =
f:
nixpkgs.lib.genAttrs nixpkgs.lib.systems.flakeExposed (
system: f (import nixpkgs { inherit system; })
);
in
{
formatter = forSystems (pkgs: pkgs.nixfmt-tree);
devShells = forSystems (
pkgs:
let
inherit (pkgs) lib stdenv;
runtimeLibs = [
pkgs.fontconfig
pkgs.freetype
]
++ lib.optionals stdenv.isLinux (
with pkgs;
[
libglvnd
libX11
libXcursor
libXi
libXrandr
libxkbcommon
wayland
]
);
in
{
default = pkgs.mkShell (
{
nativeBuildInputs = with pkgs; [
clang
pkg-config
];
buildInputs =
with pkgs;
[
rustc
cargo
rustfmt
rust-analyzer
clippy
android-tools
]
++ runtimeLibs;
RUST_SRC_PATH = "${pkgs.rustPlatform.rustLibSrc}/lib/rustlib/src/rust";
LIBCLANG_PATH = "${pkgs.llvmPackages.libclang.lib}/lib";
}
// lib.optionalAttrs stdenv.isLinux { LD_LIBRARY_PATH = lib.makeLibraryPath runtimeLibs; }
// lib.optionalAttrs stdenv.isDarwin {
DYLD_FALLBACK_LIBRARY_PATH = lib.makeLibraryPath runtimeLibs;
}
);
}
);
};
}

BIN
resources/assets/icon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 401 KiB

View file

@ -416,8 +416,11 @@
{
"ligatures": "folder-open, directory2",
"name": "folder-open",
"order": 0,
"id": 49
"order": 4,
"id": 49,
"prevSize": 28,
"code": 59696,
"tempChar": ""
},
{
"ligatures": "folder-plus, directory3",
@ -1016,8 +1019,11 @@
{
"ligatures": "cog, gear",
"name": "cog",
"order": 0,
"id": 149
"order": 3,
"id": 149,
"prevSize": 28,
"code": 59796,
"tempChar": ""
},
{
"ligatures": "cogs, gears",

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View file

@ -0,0 +1 @@
MAINICON ICON "icon.ico"

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><svg id="Discord-Logo" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 126.644 96"><defs><style>.cls-1{fill:#5865f2;}</style></defs><path id="Discord-Symbol-Blurple" class="cls-1" d="M81.15,0c-1.2376,2.1973-2.3489,4.4704-3.3591,6.794-9.5975-1.4396-19.3718-1.4396-28.9945,0-.985-2.3236-2.1216-4.5967-3.3591-6.794-9.0166,1.5407-17.8059,4.2431-26.1405,8.0568C2.779,32.5304-1.6914,56.3725.5312,79.8863c9.6732,7.1476,20.5083,12.603,32.0505,16.0884,2.6014-3.4854,4.8998-7.1981,6.8698-11.0623-3.738-1.3891-7.3497-3.1318-10.8098-5.1523.9092-.6567,1.7932-1.3386,2.6519-1.9953,20.281,9.547,43.7696,9.547,64.0758,0,.8587.7072,1.7427,1.3891,2.6519,1.9953-3.4601,2.0457-7.0718,3.7632-10.835,5.1776,1.97,3.8642,4.2683,7.5769,6.8698,11.0623,11.5419-3.4854,22.3769-8.9156,32.0509-16.0631,2.626-27.2771-4.496-50.9172-18.817-71.8548C98.9811,4.2684,90.1918,1.5659,81.1752.0505l-.0252-.0505ZM42.2802,65.4144c-6.2383,0-11.4159-5.6575-11.4159-12.6535s4.9755-12.6788,11.3907-12.6788,11.5169,5.708,11.4159,12.6788c-.101,6.9708-5.026,12.6535-11.3907,12.6535ZM84.3576,65.4144c-6.2637,0-11.3907-5.6575-11.3907-12.6535s4.9755-12.6788,11.3907-12.6788,11.4917,5.708,11.3906,12.6788c-.101,6.9708-5.026,12.6535-11.3906,12.6535Z"/></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 171 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

View file

@ -1,86 +0,0 @@
use crate::core::sync::{get_android_sdk, User};
use crate::core::utils::DisplayablePath;
use crate::gui::views::settings::Settings;
use crate::CONFIG_DIR;
use serde::{Deserialize, Serialize};
use static_init::dynamic;
use std::fs;
use std::path::PathBuf;
#[derive(Default, Debug, Serialize, Deserialize, Clone)]
pub struct Config {
pub general: GeneralSettings,
#[serde(skip_serializing_if = "Vec::is_empty", default = "Vec::new")]
pub devices: Vec<DeviceSettings>,
}
#[derive(Default, Debug, Serialize, Deserialize, Clone)]
pub struct GeneralSettings {
pub theme: String,
pub expert_mode: bool,
}
#[derive(Default, Debug, Clone)]
pub struct BackupSettings {
pub backups: Vec<DisplayablePath>,
pub selected: Option<DisplayablePath>,
pub users: Vec<User>,
pub selected_user: Option<User>,
pub backup_state: String,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct DeviceSettings {
pub device_id: String,
pub disable_mode: bool,
pub multi_user_mode: bool,
#[serde(skip)]
pub backup: BackupSettings,
}
impl Default for DeviceSettings {
fn default() -> Self {
Self {
device_id: String::new(),
multi_user_mode: get_android_sdk() > 21,
disable_mode: false,
backup: BackupSettings::default(),
}
}
}
#[dynamic]
static CONFIG_FILE: PathBuf = CONFIG_DIR.join("config.toml");
impl Config {
pub fn save_changes(settings: &Settings, device_id: &String) {
let mut config = Self::load_configuration_file();
if let Some(device) = config
.devices
.iter_mut()
.find(|x| x.device_id == *device_id)
{
*device = settings.device.clone();
} else {
debug!("config: New device settings saved");
config.devices.push(settings.device.clone());
}
config.general = settings.general.clone();
let toml = toml::to_string(&config).unwrap();
fs::write(&*CONFIG_FILE, toml).expect("Could not write config file to disk!");
}
pub fn load_configuration_file() -> Self {
match fs::read_to_string(&*CONFIG_FILE) {
Ok(s) => match toml::from_str(&s) {
Ok(config) => return config,
Err(e) => error!("Invalid config file: `{}`", e),
},
Err(e) => error!("Failed to read config file: `{}`", e),
}
error!("Restoring default config file");
let toml = toml::to_string(&Self::default()).unwrap();
fs::write(&*CONFIG_FILE, toml).expect("Could not write config file to disk!");
Self::default()
}
}

View file

@ -1,7 +0,0 @@
pub mod config;
pub mod save;
pub mod sync;
pub mod theme;
pub mod uad_lists;
pub mod update;
pub mod utils;

View file

@ -1,336 +0,0 @@
use crate::core::uad_lists::PackageState;
use crate::gui::views::list::PackageInfo;
use crate::gui::widgets::package_row::PackageRow;
use regex::Regex;
use retry::{delay::Fixed, retry, OperationResult};
use serde::{Deserialize, Serialize};
use static_init::dynamic;
use std::collections::HashSet;
use std::env;
use std::process::Command;
#[cfg(target_os = "windows")]
use std::os::windows::process::CommandExt;
#[dynamic]
static RE: Regex = Regex::new(r"\n(\S+)\s+device").unwrap();
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Phone {
pub model: String,
pub android_sdk: u8,
pub user_list: Vec<User>,
pub adb_id: String,
}
impl Default for Phone {
fn default() -> Self {
Self {
model: "fetching devices...".to_string(),
android_sdk: 0,
user_list: vec![],
adb_id: String::new(),
}
}
}
impl std::fmt::Display for Phone {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.model)
}
}
#[derive(Default, Debug, Clone, PartialEq, Eq, Copy)]
pub struct User {
pub id: u16,
pub index: usize,
pub protected: bool,
}
impl std::fmt::Display for User {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "user {}", self.id)
}
}
pub fn adb_shell_command(shell: bool, args: &str) -> Result<String, String> {
let adb_command = if shell {
vec!["shell", args]
} else {
vec![args]
};
let mut command = Command::new("adb");
command.args(adb_command);
#[cfg(target_os = "windows")]
let command = command.creation_flags(0x08000000); // do not open a cmd window
match command.output() {
Err(e) => {
error!("ADB: {}", e);
Err("ADB was not found".to_string())
}
Ok(o) => {
if o.status.success() {
Ok(String::from_utf8(o.stdout)
.map_err(|e| e.to_string())?
.trim_end()
.to_string())
} else {
let stdout = String::from_utf8(o.stdout)
.map_err(|e| e.to_string())?
.trim_end()
.to_string();
let stderr = String::from_utf8(o.stderr)
.map_err(|e| e.to_string())?
.trim_end()
.to_string();
// ADB does really weird things. Some errors are not redirected to stderr
let err = if stdout.is_empty() { stderr } else { stdout };
Err(err)
}
}
}
}
#[derive(Debug, Clone)]
pub enum CommandType {
PackageManager(PackageInfo),
Shell,
}
pub async fn perform_adb_commands(
action: String,
command_type: CommandType,
) -> Result<CommandType, ()> {
let label = match command_type {
CommandType::PackageManager(ref p) => p.removal.to_string(),
CommandType::Shell => "Shell".to_string(),
};
match adb_shell_command(true, &action) {
Ok(o) => {
// On old devices, adb commands can return the '0' exit code even if there
// is an error. On Android 4.4, ADB doesn't check if the package exists.
// It does not return any error if you try to `pm block` a non-existent package.
// Some commands are even killed by ADB before finishing and UAD can't catch
// the output.
if ["Error", "Failure"].iter().any(|&e| o.contains(e)) {
error!("[{}] {} -> {}", label, action, o);
Err(())
} else {
info!("[{}] {} -> {}", label, action, o);
Ok(command_type)
}
}
Err(err) => {
if !err.contains("[not installed for") {
error!("[{}] {} -> {}", label, action, err);
}
Err(())
}
}
}
#[allow(clippy::option_if_let_else)]
pub fn user_flag(user_id: Option<&User>) -> String {
match user_id {
Some(user_id) => format!(" --user {}", user_id.id),
None => "".to_string(),
}
}
pub fn list_all_system_packages(user_id: Option<&User>) -> String {
let action = format!("pm list packages -s -u{}", user_flag(user_id));
adb_shell_command(true, &action)
.unwrap_or_else(|_| String::new())
.replace("package:", "")
}
pub fn hashset_system_packages(state: PackageState, user_id: Option<&User>) -> HashSet<String> {
let user = user_flag(user_id);
let action = match state {
PackageState::Enabled => format!("pm list packages -s -e{user}"),
PackageState::Disabled => format!("pm list package -s -d{user}"),
_ => String::new(), // You probably don't need to use this function for anything else
};
adb_shell_command(true, &action)
.unwrap_or_default()
.replace("package:", "")
.lines()
.map(String::from)
.collect()
}
// Minimum information for processing adb commands
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)]
pub struct CorePackage {
pub name: String,
pub state: PackageState,
}
impl From<&mut PackageRow> for CorePackage {
fn from(pr: &mut PackageRow) -> Self {
Self {
name: pr.name.clone(),
state: pr.state,
}
}
}
impl From<PackageRow> for CorePackage {
fn from(pr: PackageRow) -> Self {
Self {
name: pr.name.clone(),
state: pr.state,
}
}
}
impl From<&PackageRow> for CorePackage {
fn from(pr: &PackageRow) -> Self {
Self {
name: pr.name.clone(),
state: pr.state,
}
}
}
pub fn apply_pkg_state_commands(
package: &CorePackage,
wanted_state: PackageState,
selected_user: &User,
phone: &Phone,
) -> Vec<String> {
// https://github.com/Universal-Debloater-Alliance/universal-android-debloater/wiki/ADB-reference
// ALWAYS PUT THE COMMAND THAT CHANGES THE PACKAGE STATE FIRST!
let commands = match wanted_state {
PackageState::Enabled => {
match package.state {
PackageState::Disabled => match phone.android_sdk {
i if i >= 23 => vec!["pm enable"],
_ => vec!["pm enable"],
},
PackageState::Uninstalled => match phone.android_sdk {
i if i >= 23 => vec!["cmd package install-existing"],
21 | 22 => vec!["pm unhide"],
19 | 20 => vec!["pm unblock", "pm clear"],
_ => vec![], // Impossible action already prevented by the GUI
},
_ => 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"],
_ => 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"], // Android Lollipop (5.x)
19 | 20 => vec!["pm block", "pm clear"], // Android KitKat (4.4/4.4W)
_ => vec!["pm uninstall"], // Disable mode is unavailable on older devices because the specific ADB commands need root
},
_ => vec![],
},
PackageState::All => vec![],
};
if phone.android_sdk < 21 {
request_builder(&commands, &package.name, None)
} else {
request_builder(&commands, &package.name, Some(selected_user))
}
}
pub fn request_builder(commands: &[&str], package: &str, user: Option<&User>) -> Vec<String> {
#[allow(clippy::option_if_let_else)]
match user {
Some(u) => commands
.iter()
.map(|c| format!("{} --user {} {}", c, u.id, package))
.collect(),
None => commands.iter().map(|c| format!("{c} {package}")).collect(),
}
}
pub fn get_phone_model() -> String {
adb_shell_command(true, "getprop ro.product.model").unwrap_or_else(|err| {
println!("ERROR: {err}");
if err.contains("adb: no devices/emulators found") {
"no devices/emulators found".to_string()
} else {
err
}
})
}
pub fn get_android_sdk() -> u8 {
adb_shell_command(true, "getprop ro.build.version.sdk").map_or(0, |sdk| sdk.parse().unwrap())
}
pub fn get_phone_brand() -> String {
format!(
"{} {}",
adb_shell_command(true, "getprop ro.product.brand")
.map(|s| s.trim().to_string())
.unwrap_or_default(),
get_phone_model()
)
}
pub fn is_protected_user(user_id: &str) -> bool {
adb_shell_command(true, &format!("pm list packages -s --user {user_id}")).is_err()
}
pub fn get_user_list() -> Vec<User> {
#[dynamic]
static RE: Regex = Regex::new(r"\{([0-9]+)").unwrap();
adb_shell_command(true, "pm list users")
.map(|users| {
RE.find_iter(&users)
.enumerate()
.map(|(i, u)| User {
id: u.as_str()[1..].parse().unwrap(),
index: i,
protected: is_protected_user(&u.as_str()[1..]),
})
.collect()
})
.unwrap_or_default()
}
// getprop ro.serialno
pub async fn get_devices_list() -> Vec<Phone> {
retry(
Fixed::from_millis(500).take(120),
|| match adb_shell_command(false, "devices") {
Ok(devices) => {
let mut device_list: Vec<Phone> = vec![];
if !RE.is_match(&devices) {
return OperationResult::Retry(vec![]);
}
for device in RE.captures_iter(&devices) {
env::set_var("ANDROID_SERIAL", &device[1]);
device_list.push(Phone {
model: get_phone_brand(),
android_sdk: get_android_sdk(),
user_list: get_user_list(),
adb_id: device[1].to_string(),
});
}
OperationResult::Ok(device_list)
}
Err(err) => {
error!("get_device_list() -> {}", err);
let test: Vec<Phone> = vec![];
OperationResult::Retry(test)
}
},
)
.unwrap_or_default()
}

View file

@ -1,114 +0,0 @@
use iced::{color, Color};
#[derive(Default, Debug, PartialEq, Eq, Copy, Clone)]
pub enum Theme {
#[default]
Lupin,
Dark,
Light,
}
#[derive(Debug, Clone, Copy)]
pub struct BaseColors {
pub background: Color,
pub foreground: Color,
}
#[derive(Debug, Clone, Copy)]
pub struct NormalColors {
pub primary: Color,
pub secondary: Color,
pub surface: Color,
pub error: Color,
}
#[derive(Debug, Clone, Copy)]
pub struct BrightColors {
pub primary: Color,
pub secondary: Color,
pub surface: Color,
pub error: Color,
}
#[derive(Debug, Clone, Copy)]
pub struct ColorPalette {
pub base: BaseColors,
pub normal: NormalColors,
pub bright: BrightColors,
}
impl Theme {
pub const ALL: [Self; 3] = [Self::Lupin, Self::Dark, Self::Light];
pub fn palette(self) -> ColorPalette {
match self {
Self::Dark => ColorPalette {
base: BaseColors {
background: color!(0x111111),
foreground: color!(0x1C1C1C),
},
normal: NormalColors {
primary: color!(0x5E4266),
secondary: color!(0x386e50),
surface: color!(0x828282),
error: color!(0x992B2B),
},
bright: BrightColors {
primary: color!(0xBA84FC),
secondary: color!(0x49eb7a),
surface: color!(0xE0E0E0),
error: color!(0xC13047),
},
},
Self::Light => ColorPalette {
base: BaseColors {
background: color!(0xEEEEEE),
foreground: color!(0xE0E0E0),
},
normal: NormalColors {
primary: color!(0x230F08),
secondary: color!(0xF9D659),
surface: color!(0x818181),
error: color!(0x992B2B),
},
bright: BrightColors {
primary: color!(0x673AB7),
secondary: color!(0x3797A4),
surface: color!(0x000000),
error: color!(0xC13047),
},
},
Self::Lupin => ColorPalette {
base: BaseColors {
background: color!(0x282a36),
foreground: color!(0x353746),
},
normal: NormalColors {
primary: color!(0x58406F),
secondary: color!(0x386e50),
surface: color!(0xa2a4a3),
error: color!(0xA13034),
},
bright: BrightColors {
primary: color!(0xbd94f9),
secondary: color!(0x49eb7a),
surface: color!(0xf4f8f3),
error: color!(0xE63E6D),
},
},
}
}
}
impl std::fmt::Display for Theme {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}",
match self {
Self::Dark => "Dark",
Self::Light => "Light",
Self::Lupin => "Lupin",
}
)
}
}

View file

@ -1,136 +0,0 @@
use crate::core::sync::{hashset_system_packages, list_all_system_packages, User};
use crate::core::theme::Theme;
use crate::core::uad_lists::{Package, PackageState, Removal, UadList};
use crate::gui::widgets::package_row::PackageRow;
use chrono::offset::Utc;
use chrono::DateTime;
use std::collections::HashMap;
use std::path::PathBuf;
use std::process::Command;
use std::{fmt, fs};
pub fn fetch_packages(
uad_lists: &HashMap<String, Package>,
user_id: Option<&User>,
) -> Vec<PackageRow> {
let all_system_packages = list_all_system_packages(user_id); // installed and uninstalled packages
let enabled_system_packages = hashset_system_packages(PackageState::Enabled, user_id);
let disabled_system_packages = hashset_system_packages(PackageState::Disabled, user_id);
let mut description;
let mut uad_list;
let mut state;
let mut removal;
let mut user_package: Vec<PackageRow> = Vec::new();
for p_name in all_system_packages.lines() {
state = PackageState::Uninstalled;
description = "[No description] : CONTRIBUTION WELCOMED";
uad_list = UadList::Unlisted;
removal = Removal::Unlisted;
if uad_lists.contains_key(p_name) {
description = &uad_lists.get(p_name).unwrap().description;
if description.is_empty() {
description = "[No description] : CONTRIBUTION WELCOMED";
};
uad_list = uad_lists.get(p_name).unwrap().list;
removal = uad_lists.get(p_name).unwrap().removal;
}
if enabled_system_packages.contains(p_name) {
state = PackageState::Enabled;
} else if disabled_system_packages.contains(p_name) {
state = PackageState::Disabled;
}
let package_row =
PackageRow::new(p_name, state, description, uad_list, removal, false, false);
user_package.push(package_row);
}
user_package.sort_by(|a, b| a.name.to_lowercase().cmp(&b.name.to_lowercase()));
user_package
}
pub fn string_to_theme(theme: &str) -> Theme {
match theme {
"Dark" => Theme::Dark,
"Light" => Theme::Light,
"Lupin" => Theme::Lupin,
_ => Theme::Lupin,
}
}
pub fn setup_uad_dir(dir: Option<PathBuf>) -> PathBuf {
let dir = dir.unwrap().join("uad");
fs::create_dir_all(&dir).expect("Can't create cache directory");
dir
}
pub fn open_url(dir: PathBuf) {
#[cfg(target_os = "windows")]
let output = Command::new("explorer").args([dir]).output();
#[cfg(target_os = "macos")]
let output = Command::new("open").args([dir]).output();
#[cfg(not(any(target_os = "macos", target_os = "windows")))]
let output = Command::new("xdg-open").args([dir]).output();
match output {
Ok(o) => {
if !o.status.success() {
let stderr = String::from_utf8(o.stderr).unwrap().trim_end().to_string();
error!("Can't open the following URL: {}", stderr);
}
}
Err(e) => error!("Failed to run command to open the file explorer: {}", e),
}
}
#[rustfmt::skip]
#[allow(clippy::option_if_let_else)]
pub fn last_modified_date(file: PathBuf) -> DateTime<Utc> {
fs::metadata(file).map_or_else(|_| Utc::now(), |metadata| match metadata.modified() {
Ok(time) => time.into(),
Err(_) => Utc::now(),
})
}
pub fn format_diff_time_from_now(date: DateTime<Utc>) -> String {
let now: DateTime<Utc> = Utc::now();
let last_update = now - date;
if last_update.num_days() == 0 {
if last_update.num_hours() == 0 {
last_update.num_minutes().to_string() + " min(s) ago"
} else {
last_update.num_hours().to_string() + " hour(s) ago"
}
} else {
last_update.num_days().to_string() + " day(s) ago"
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct DisplayablePath {
pub path: PathBuf,
}
impl fmt::Display for DisplayablePath {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let stem = self.path.file_stem().map_or_else(
|| {
error!("[PATH STEM]: No file stem found");
"[File steam not found]".to_string()
},
|p| match p.to_os_string().into_string() {
Ok(stem) => stem,
Err(e) => {
error!("[PATH ENCODING]: {:?}", e);
"[PATH ENCODING ERROR]".to_string()
}
},
);
write!(f, "{stem}")
}
}

View file

@ -1,367 +0,0 @@
pub mod style;
pub mod views;
pub mod widgets;
use crate::core::sync::{get_devices_list, perform_adb_commands, CommandType, Phone};
use crate::core::theme::Theme;
use crate::core::uad_lists::UadListState;
use crate::core::update::{get_latest_release, Release, SelfUpdateState, SelfUpdateStatus};
use crate::core::utils::string_to_theme;
use views::about::{About as AboutView, Message as AboutMessage};
use views::list::{List as AppsView, LoadingState as ListLoadingState, Message as AppsMessage};
use views::settings::{Message as SettingsMessage, Settings as SettingsView};
use widgets::navigation_menu::nav_menu;
use iced::widget::column;
use iced::{
window::Settings as Window, Alignment, Application, Command, Element, Length, Renderer,
Settings,
};
use std::{env, path::PathBuf};
#[cfg(feature = "self-update")]
use crate::core::update::{bin_name, download_update_to_temp_file, remove_file};
#[derive(Default, Debug, Clone)]
enum View {
#[default]
List,
About,
Settings,
}
#[derive(Default, Clone)]
pub struct UpdateState {
self_update: SelfUpdateState,
uad_list: UadListState,
}
#[derive(Default, Clone)]
pub struct UadGui {
view: View,
apps_view: AppsView,
about_view: AboutView,
settings_view: SettingsView,
devices_list: Vec<Phone>,
selected_device: Option<Phone>, // index of devices_list
update_state: UpdateState,
nb_running_async_adb_commands: u32,
}
#[derive(Debug, Clone)]
pub enum Message {
// Navigation Panel
AboutPressed,
SettingsPressed,
AppsPress,
DeviceSelected(Phone),
AboutAction(AboutMessage),
AppsAction(AppsMessage),
SettingsAction(SettingsMessage),
RefreshButtonPressed,
RebootButtonPressed,
LoadDevices(Vec<Phone>),
_NewReleaseDownloaded(Result<(PathBuf, PathBuf), ()>),
GetLatestRelease(Result<Option<Release>, ()>),
Nothing,
}
impl Application for UadGui {
type Theme = Theme;
type Executor = iced::executor::Default;
type Message = Message;
type Flags = ();
fn new(_flags: ()) -> (Self, Command<Message>) {
(
Self::default(),
Command::batch([
Command::perform(get_devices_list(), Message::LoadDevices),
Command::perform(
async move { get_latest_release() },
Message::GetLatestRelease,
),
]),
)
}
fn theme(&self) -> Theme {
string_to_theme(&self.settings_view.general.theme)
}
fn title(&self) -> String {
String::from("Universal Android Debloater")
}
fn update(&mut self, msg: Message) -> Command<Message> {
match msg {
#[allow(clippy::option_if_let_else)]
Message::LoadDevices(devices_list) => {
self.selected_device = match &self.selected_device {
Some(s_device) => {
// Try to reload last selected phone
devices_list
.iter()
.find(|phone| phone.adb_id == s_device.adb_id)
.cloned()
}
None => devices_list.first().cloned(),
};
self.devices_list = devices_list;
#[allow(unused_must_use)]
{
self.update(Message::SettingsAction(SettingsMessage::LoadDeviceSettings));
}
self.update(Message::AppsAction(AppsMessage::LoadUadList(true)))
}
Message::AppsPress => {
self.view = View::List;
Command::none()
}
Message::AboutPressed => {
self.view = View::About;
self.update_state.self_update = SelfUpdateState::default();
Command::perform(
async move { get_latest_release() },
Message::GetLatestRelease,
)
}
Message::SettingsPressed => {
self.view = View::Settings;
Command::none()
}
Message::RefreshButtonPressed => {
self.apps_view = AppsView::default();
Command::perform(get_devices_list(), Message::LoadDevices)
}
Message::RebootButtonPressed => {
self.apps_view = AppsView::default();
self.selected_device = None;
self.devices_list = vec![];
Command::perform(
perform_adb_commands("reboot".to_string(), CommandType::Shell),
|_| Message::Nothing,
)
}
Message::AppsAction(msg) => self
.apps_view
.update(
&mut self.settings_view,
&mut self.selected_device.clone().unwrap_or_default(),
&mut self.update_state.uad_list,
msg,
)
.map(Message::AppsAction),
Message::SettingsAction(msg) => {
match msg {
SettingsMessage::RestoringDevice(ref output) => {
self.nb_running_async_adb_commands -= 1;
self.view = View::List;
#[allow(unused_must_use)]
{
self.apps_view.update(
&mut self.settings_view,
&mut self.selected_device.clone().unwrap_or_default(),
&mut self.update_state.uad_list,
AppsMessage::RestoringDevice(output.clone()),
);
}
if self.nb_running_async_adb_commands == 0 {
return self.update(Message::RefreshButtonPressed);
}
}
SettingsMessage::MultiUserMode(toggled) => {
if toggled {
for user in self.apps_view.phone_packages.clone() {
for (i, _) in
user.iter().enumerate().filter(|&(_, pkg)| pkg.selected)
{
for u in self
.selected_device
.as_ref()
.unwrap()
.user_list
.iter()
.filter(|&u| !u.protected)
{
self.apps_view.phone_packages[u.index][i].selected = true;
}
}
}
}
}
_ => (),
}
self.settings_view
.update(
&self.selected_device.clone().unwrap_or_default(),
&self.apps_view.phone_packages,
&mut self.nb_running_async_adb_commands,
msg,
)
.map(Message::SettingsAction)
}
Message::AboutAction(msg) => {
self.about_view.update(msg.clone());
match msg {
AboutMessage::UpdateUadLists => {
self.update_state.uad_list = UadListState::Downloading;
self.apps_view.loading_state =
ListLoadingState::DownloadingList(String::new());
self.update(Message::AppsAction(AppsMessage::LoadUadList(true)))
}
AboutMessage::DoSelfUpdate => {
#[cfg(feature = "self-update")]
if self.update_state.self_update.latest_release.is_some() {
self.update_state.self_update.status = SelfUpdateStatus::Updating;
self.apps_view.loading_state =
ListLoadingState::_UpdatingUad(String::new());
let bin_name = bin_name().to_owned();
let release = self
.update_state
.self_update
.latest_release
.as_ref()
.unwrap()
.clone();
Command::perform(
download_update_to_temp_file(bin_name, release),
Message::_NewReleaseDownloaded,
)
} else {
Command::none()
}
#[cfg(not(feature = "self-update"))]
Command::none()
}
AboutMessage::UrlPressed(_) => Command::none(),
}
}
Message::DeviceSelected(s_device) => {
self.selected_device = Some(s_device.clone());
self.view = View::List;
env::set_var("ANDROID_SERIAL", s_device.adb_id);
info!("{:-^65}", "-");
info!(
"ANDROID_SDK: {} | DEVICE: {}",
s_device.android_sdk, s_device.model
);
info!("{:-^65}", "-");
self.apps_view.loading_state = ListLoadingState::FindingPhones(String::new());
#[allow(unused_must_use)]
{
self.update(Message::SettingsAction(SettingsMessage::LoadDeviceSettings));
}
self.update(Message::AppsAction(AppsMessage::LoadPhonePackages((
self.apps_view.uad_lists.clone(),
UadListState::Done,
))))
}
Message::_NewReleaseDownloaded(res) => {
debug!("UAD update has been download!");
#[cfg(feature = "self-update")]
if let Ok((relaunch_path, cleanup_path)) = res {
// Remove first arg, which is path to binary. We don't use this first
// arg as binary path because it's not reliable, per the docs.
let mut args = std::env::args();
args.next();
let mut args: Vec<_> = args.collect();
// Remove the `--self-update-temp` arg from args if it exists,
// since we need to pass it cleanly. Otherwise new process will
// fail during arg parsing.
if let Some(idx) = args.iter().position(|a| a == "--self-update-temp") {
args.remove(idx);
// Remove path passed after this arg
args.remove(idx);
}
match std::process::Command::new(relaunch_path)
.args(args)
.arg("--self-update-temp")
.arg(&cleanup_path)
.spawn()
{
Ok(_) => {
if let Err(e) = remove_file(cleanup_path) {
error!("Could not remove temp update file: {}", e);
}
std::process::exit(0)
}
Err(error) => {
if let Err(e) = remove_file(cleanup_path) {
error!("Could not remove temp update file: {}", e);
}
error!("Failed to update UAD: {}", error);
}
}
} else {
error!("Failed to update UAD!");
}
Command::none()
}
Message::GetLatestRelease(release) => {
match release {
Ok(r) => {
self.update_state.self_update.status = SelfUpdateStatus::Done;
self.update_state.self_update.latest_release = r;
}
Err(_) => self.update_state.self_update.status = SelfUpdateStatus::Failed,
};
Command::none()
}
Message::Nothing => Command::none(),
}
}
fn view(&self) -> Element<Self::Message, Renderer<Self::Theme>> {
let navigation_container = nav_menu(
&self.devices_list,
self.selected_device.clone(),
&self.apps_view,
&self.update_state.self_update,
);
let selected_device = self.selected_device.clone().unwrap_or_default();
let main_container = match self.view {
View::List => self
.apps_view
.view(&self.settings_view, &selected_device)
.map(Message::AppsAction),
View::About => self
.about_view
.view(&self.update_state)
.map(Message::AboutAction),
View::Settings => self
.settings_view
.view(&selected_device)
.map(Message::SettingsAction),
};
column![navigation_container, main_container]
.width(Length::Fill)
.align_items(Alignment::Center)
.into()
}
}
impl UadGui {
pub fn start() -> iced::Result {
Self::run(Settings {
window: Window {
size: (820, 640),
resizable: true,
decorations: true,
..iced::window::Settings::default()
},
default_text_size: 17.0,
..Settings::default()
})
}
}

View file

@ -1,510 +0,0 @@
use crate::core::theme::Theme;
use iced::overlay::menu;
use iced::widget::{
button, checkbox, container, pick_list, radio, rule, scrollable, text, text_input,
};
use iced::{application, Background, Color};
#[derive(Default, Debug, Clone, Copy)]
pub enum Application {
#[default]
Default,
}
impl application::StyleSheet for Theme {
type Style = Application;
fn appearance(&self, _style: &Self::Style) -> application::Appearance {
application::Appearance {
background_color: self.palette().base.background,
text_color: self.palette().bright.surface,
}
}
}
#[derive(Default, Debug, Clone, Copy)]
pub enum Container {
#[default]
Invisible,
Frame,
BorderedFrame,
Tooltip,
Background,
}
impl container::StyleSheet for Theme {
type Style = Container;
fn appearance(&self, style: &Self::Style) -> container::Appearance {
match style {
Container::Invisible => container::Appearance::default(),
Container::Frame => container::Appearance {
background: Some(Background::Color(self.palette().base.foreground)),
text_color: Some(self.palette().bright.surface),
border_radius: 5.0,
..container::Appearance::default()
},
Container::BorderedFrame => container::Appearance {
background: Some(Background::Color(self.palette().base.foreground)),
text_color: Some(self.palette().bright.surface),
border_radius: 5.0,
border_width: 1.0,
border_color: self.palette().normal.error,
},
Container::Tooltip => container::Appearance {
background: Some(Background::Color(self.palette().base.foreground)),
text_color: Some(self.palette().bright.surface),
border_radius: 8.0,
border_width: 1.0,
border_color: self.palette().normal.primary,
},
Container::Background => container::Appearance {
background: Some(Background::Color(self.palette().base.background)),
text_color: Some(self.palette().bright.surface),
border_radius: 5.0,
..container::Appearance::default()
},
}
}
}
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)]
pub enum Button {
#[default]
Primary,
Unavailable,
SelfUpdate,
Refresh,
UninstallPackage,
RestorePackage,
NormalPackage,
SelectedPackage,
}
impl button::StyleSheet for Theme {
type Style = Button;
fn active(&self, style: &Self::Style) -> button::Appearance {
let p = self.palette();
let appearance = button::Appearance {
border_width: 1.0,
border_radius: 2.0,
..button::Appearance::default()
};
let active_appearance = |bg: Option<Color>, mc| button::Appearance {
background: Some(Background::Color(bg.unwrap_or(p.base.foreground))),
border_color: Color { a: 0.5, ..mc },
text_color: mc,
..appearance
};
match style {
Button::Primary | Button::SelfUpdate | Button::Refresh => {
active_appearance(None, p.bright.primary)
}
Button::RestorePackage => active_appearance(None, p.bright.secondary),
Button::NormalPackage => button::Appearance {
background: Some(Background::Color(p.base.foreground)),
text_color: p.bright.surface,
border_radius: 5.0,
border_width: 0.0,
border_color: p.base.background,
..appearance
},
Button::SelectedPackage => button::Appearance {
background: Some(Background::Color(Color {
a: 0.25,
..p.normal.primary
})),
text_color: p.bright.primary,
border_radius: 5.0,
border_width: 0.0,
border_color: p.normal.primary,
..appearance
},
Button::Unavailable | Button::UninstallPackage => {
active_appearance(None, p.bright.error)
}
}
}
fn hovered(&self, style: &Self::Style) -> button::Appearance {
let active = self.active(style);
let p = self.palette();
let hover_appearance = |bg, tc: Option<Color>| button::Appearance {
background: Some(Background::Color(Color { a: 0.25, ..bg })),
text_color: tc.unwrap_or(bg),
..active
};
match style {
Button::Primary | Button::SelfUpdate | Button::Refresh => {
hover_appearance(p.bright.primary, None)
}
Button::NormalPackage => hover_appearance(p.normal.primary, Some(p.bright.surface)),
Button::SelectedPackage => hover_appearance(p.normal.primary, None),
Button::RestorePackage => hover_appearance(p.bright.secondary, None),
Button::Unavailable | Button::UninstallPackage => {
hover_appearance(p.bright.error, None)
}
}
}
fn pressed(&self, style: &Self::Style) -> button::Appearance {
self.active(style)
}
fn disabled(&self, style: &Self::Style) -> button::Appearance {
let active = self.active(style);
let p = self.palette();
let disabled_appearance = |bg, tc: Option<Color>| button::Appearance {
background: Some(Background::Color(Color { a: 0.05, ..bg })),
text_color: Color {
a: 0.50,
..tc.unwrap_or(bg)
},
..active
};
match style {
Button::RestorePackage => disabled_appearance(p.normal.primary, Some(p.bright.primary)),
Button::UninstallPackage => disabled_appearance(p.bright.error, None),
Button::Primary => disabled_appearance(p.bright.primary, Some(p.bright.primary)),
_ => active,
}
}
}
#[derive(Default, Debug, Clone, Copy)]
pub enum Scrollable {
#[default]
Description,
Packages,
}
impl scrollable::StyleSheet for Theme {
type Style = Scrollable;
fn active(&self, style: &Self::Style) -> scrollable::Scrollbar {
let from_appearance = |c: Color| scrollable::Scrollbar {
background: Some(Background::Color(Color::TRANSPARENT)),
border_radius: 5.0,
border_width: 0.0,
border_color: Color::TRANSPARENT,
scroller: scrollable::Scroller {
color: c,
border_radius: 5.0,
border_width: 1.0,
border_color: Color::TRANSPARENT,
},
};
match style {
Scrollable::Description => from_appearance(self.palette().normal.surface),
Scrollable::Packages => from_appearance(self.palette().base.foreground),
}
}
fn hovered(&self, style: &Self::Style, _mouse_over_scrollbar: bool) -> scrollable::Scrollbar {
scrollable::Scrollbar {
scroller: self.active(style).scroller,
..self.active(style)
}
}
fn dragging(&self, style: &Self::Style) -> scrollable::Scrollbar {
let hovered = self.hovered(style, true);
scrollable::Scrollbar {
scroller: hovered.scroller,
..hovered
}
}
}
#[derive(Default, Debug, Clone, Copy)]
pub enum CheckBox {
#[default]
PackageEnabled,
PackageDisabled,
SettingsEnabled,
SettingsDisabled,
}
impl checkbox::StyleSheet for Theme {
type Style = CheckBox;
fn active(&self, style: &Self::Style, _is_checked: bool) -> checkbox::Appearance {
match style {
CheckBox::PackageEnabled => checkbox::Appearance {
background: Background::Color(self.palette().base.background),
icon_color: self.palette().bright.primary,
border_radius: 5.0,
border_width: 1.0,
border_color: self.palette().base.background,
text_color: Some(self.palette().bright.surface),
},
CheckBox::PackageDisabled => checkbox::Appearance {
background: Background::Color(Color {
a: 0.55,
..self.palette().base.background
}),
icon_color: self.palette().bright.primary,
border_radius: 5.0,
border_width: 1.0,
border_color: self.palette().normal.primary,
text_color: Some(self.palette().normal.primary),
},
CheckBox::SettingsEnabled => checkbox::Appearance {
background: Background::Color(self.palette().base.background),
icon_color: self.palette().bright.primary,
border_radius: 5.0,
border_width: 1.0,
border_color: self.palette().bright.primary,
text_color: Some(self.palette().bright.surface),
},
CheckBox::SettingsDisabled => checkbox::Appearance {
background: Background::Color(self.palette().base.foreground),
icon_color: self.palette().bright.primary,
border_radius: 5.0,
border_width: 1.0,
border_color: self.palette().normal.primary,
text_color: Some(self.palette().bright.surface),
},
}
}
fn hovered(&self, style: &Self::Style, is_checked: bool) -> checkbox::Appearance {
let from_appearance = || checkbox::Appearance {
background: Background::Color(self.palette().base.foreground),
icon_color: self.palette().bright.primary,
border_radius: 5.0,
border_width: 2.0,
border_color: self.palette().bright.primary,
text_color: Some(self.palette().bright.surface),
};
match style {
CheckBox::PackageEnabled | CheckBox::SettingsEnabled => from_appearance(),
CheckBox::PackageDisabled | CheckBox::SettingsDisabled => {
self.active(style, is_checked)
}
}
}
}
#[derive(Default, Debug, Clone, Copy)]
pub enum TextInput {
#[default]
Default,
}
impl text_input::StyleSheet for Theme {
type Style = TextInput;
fn active(&self, _style: &Self::Style) -> text_input::Appearance {
text_input::Appearance {
background: Background::Color(self.palette().base.foreground),
border_radius: 5.0,
border_width: 0.0,
border_color: self.palette().base.foreground,
icon_color: Color {
a: 0.5,
..self.palette().normal.primary
},
}
}
fn focused(&self, _style: &Self::Style) -> text_input::Appearance {
text_input::Appearance {
background: Background::Color(self.palette().base.foreground),
border_radius: 2.0,
border_width: 1.0,
border_color: Color {
a: 0.5,
..self.palette().normal.primary
},
icon_color: Color {
a: 0.5,
..self.palette().normal.primary
},
}
}
fn disabled_color(
&self,
_: &<Self as iced::widget::text_input::StyleSheet>::Style,
) -> iced::Color {
todo!()
}
fn disabled(&self, _style: &Self::Style) -> text_input::Appearance {
text_input::Appearance {
background: Background::Color(self.palette().base.background),
border_radius: 2.0,
border_width: 1.0,
border_color: Color {
a: 0.5,
..self.palette().base.foreground
},
icon_color: Color {
a: 0.5,
..self.palette().base.foreground
},
}
}
fn placeholder_color(&self, _style: &Self::Style) -> Color {
self.palette().normal.surface
}
fn value_color(&self, _style: &Self::Style) -> Color {
self.palette().bright.primary
}
fn selection_color(&self, _style: &Self::Style) -> Color {
self.palette().normal.primary
}
/// Produces the style of an hovered text input.
fn hovered(&self, style: &Self::Style) -> text_input::Appearance {
self.focused(style)
}
}
#[derive(Default, Debug, Clone, Copy)]
pub enum PickList {
#[default]
Default,
}
impl menu::StyleSheet for Theme {
type Style = ();
fn appearance(&self, _style: &Self::Style) -> menu::Appearance {
let p = self.palette();
menu::Appearance {
text_color: p.bright.surface,
background: p.base.background.into(),
border_width: 1.0,
border_radius: 2.0,
border_color: p.base.background,
selected_text_color: p.bright.surface,
selected_background: p.normal.primary.into(),
}
}
}
impl pick_list::StyleSheet for Theme {
type Style = ();
fn active(&self, _style: &()) -> pick_list::Appearance {
pick_list::Appearance {
text_color: self.palette().bright.surface,
background: self.palette().base.background.into(),
border_width: 1.0,
border_color: Color {
a: 0.5,
..self.palette().normal.primary
},
border_radius: 2.0,
handle_color: self.palette().bright.surface,
placeholder_color: self.palette().bright.surface,
}
}
fn hovered(&self, style: &()) -> pick_list::Appearance {
let active = self.active(style);
pick_list::Appearance {
border_color: self.palette().normal.primary,
..active
}
}
}
#[derive(Default, Clone, Copy)]
pub enum Text {
#[default]
Default,
Ok,
Danger,
Commentary,
Color(Color),
}
impl From<Color> for Text {
fn from(color: Color) -> Self {
Self::Color(color)
}
}
impl text::StyleSheet for Theme {
type Style = Text;
fn appearance(&self, style: Self::Style) -> text::Appearance {
match style {
Text::Default => text::Appearance::default(),
Text::Ok => text::Appearance {
color: Some(self.palette().bright.secondary),
},
Text::Danger => text::Appearance {
color: Some(self.palette().bright.error),
},
Text::Commentary => text::Appearance {
color: Some(self.palette().normal.surface),
},
Text::Color(c) => text::Appearance { color: Some(c) },
}
}
}
impl radio::StyleSheet for Theme {
type Style = ();
fn active(&self, _style: &Self::Style, _is_selected: bool) -> radio::Appearance {
radio::Appearance {
background: Color::TRANSPARENT.into(),
dot_color: self.palette().bright.primary,
border_width: 1.0,
border_color: self.palette().bright.primary,
text_color: None,
}
}
fn hovered(&self, style: &Self::Style, _is_selected: bool) -> radio::Appearance {
let active = self.active(style, true);
radio::Appearance {
dot_color: self.palette().bright.primary,
border_color: self.palette().bright.primary,
border_width: 2.0,
..active
}
}
}
#[derive(Default, Clone, Copy)]
pub enum Rule {
#[default]
Default,
}
impl rule::StyleSheet for Theme {
type Style = Rule;
fn appearance(&self, style: &Self::Style) -> rule::Appearance {
match style {
Rule::Default => rule::Appearance {
color: self.palette().bright.surface,
width: 2,
radius: 2.0,
fill_mode: rule::FillMode::Full,
},
}
}
}

View file

@ -1,145 +0,0 @@
use crate::core::theme::Theme;
use crate::core::utils::{last_modified_date, open_url};
use crate::gui::{style, UpdateState};
use crate::CACHE_DIR;
use iced::widget::{button, column, container, row, text, Space};
use iced::{Alignment, Element, Length, Renderer};
use std::path::PathBuf;
#[cfg(feature = "self-update")]
use crate::core::update::SelfUpdateStatus;
#[derive(Default, Debug, Clone)]
pub struct About {}
#[derive(Debug, Clone)]
pub enum Message {
UrlPressed(PathBuf),
UpdateUadLists,
DoSelfUpdate,
}
impl About {
pub fn update(&mut self, msg: Message) {
if let Message::UrlPressed(url) = msg {
open_url(url);
}
// other events are handled by UadGui update()
}
pub fn view(&self, update_state: &UpdateState) -> Element<Message, Renderer<Theme>> {
let about_text = text(
"Universal Android Debloater (UAD) is a Free and Open-Source community project aiming at simplifying \
the removal of pre-installed apps on any Android device.",
);
let descr_container = container(about_text)
.width(Length::Fill)
.padding(25)
.style(style::Container::Frame);
let date = last_modified_date(CACHE_DIR.join("uad_lists.json"));
let uad_list_text = text(format!("Documentation: v{}", date.format("%Y%m%d"))).width(250);
let last_update_text = text(update_state.uad_list.to_string());
let uad_lists_btn = button("Update")
.on_press(Message::UpdateUadLists)
.padding(5)
.style(style::Button::Primary);
#[cfg(feature = "self-update")]
let self_update_btn = button("Update")
.on_press(Message::DoSelfUpdate)
.padding(5)
.style(style::Button::Primary);
#[cfg(feature = "self-update")]
let uad_version_text =
text(format!("UAD version: v{}", env!("CARGO_PKG_VERSION"))).width(250);
#[cfg(feature = "self-update")]
#[rustfmt::skip]
let self_update_text = update_state.self_update.latest_release.as_ref().map_or_else(||
if update_state.self_update.status == SelfUpdateStatus::Done {
"(No update available)".to_string()
} else {
update_state.self_update.status.to_string()
}, |r| if update_state.self_update.status == SelfUpdateStatus::Updating {
update_state.self_update.status.to_string()
} else {
format!("(v{} available)", r.tag_name)
});
#[cfg(feature = "self-update")]
let last_self_update_text = text(self_update_text).style(style::Text::Default);
#[cfg(feature = "self-update")]
let self_update_row = row![uad_version_text, self_update_btn, last_self_update_text,]
.align_items(Alignment::Center)
.spacing(10)
.width(550);
let uad_list_row = row![uad_list_text, uad_lists_btn, last_update_text,]
.align_items(Alignment::Center)
.spacing(10)
.width(550);
#[cfg(feature = "self-update")]
let update_column = column![uad_list_row, self_update_row]
.align_items(Alignment::Center)
.spacing(10);
#[cfg(not(feature = "self-update"))]
let update_column = column![uad_list_row]
.align_items(Alignment::Center)
.spacing(10);
let update_container = container(update_column)
.width(Length::Fill)
.center_x()
.padding(10)
.style(style::Container::Frame);
let website_btn = button("Github page")
.on_press(Message::UrlPressed(PathBuf::from(
"https://github.com/Universal-Debloater-Alliance/universal-android-debloater",
)))
.padding(5)
.style(style::Button::Primary);
let issue_btn = button("Have an issue?")
.on_press(Message::UrlPressed(PathBuf::from(
"https://github.com/Universal-Debloater-Alliance/universal-android-debloater/issues",
)))
.padding(5)
.style(style::Button::Primary);
let log_btn = button("Locate the logfiles")
.on_press(Message::UrlPressed(CACHE_DIR.to_path_buf()))
.padding(5)
.style(style::Button::Primary);
let wiki_btn = button("Wiki")
.on_press(Message::UrlPressed(PathBuf::from(
"https://github.com/Universal-Debloater-Alliance/universal-android-debloater/wiki",
)))
.padding(5)
.style(style::Button::Primary);
let row = row![website_btn, wiki_btn, issue_btn, log_btn,].spacing(20);
let content = column![
Space::new(Length::Fill, Length::Shrink),
descr_container,
update_container,
row,
]
.width(Length::Fill)
.spacing(20)
.align_items(Alignment::Center);
container(content)
.width(Length::Fill)
.height(Length::Fill)
.padding(10)
.into()
}
}

View file

@ -1,840 +0,0 @@
use crate::core::config::DeviceSettings;
use crate::core::sync::{apply_pkg_state_commands, perform_adb_commands, CommandType, Phone, User};
use crate::core::theme::Theme;
use crate::core::uad_lists::{
load_debloat_lists, Opposite, Package, PackageState, Removal, UadList, UadListState,
};
use crate::core::utils::fetch_packages;
use crate::gui::style;
use crate::gui::widgets::navigation_menu::ICONS;
use std::collections::HashMap;
use std::env;
use crate::gui::views::settings::Settings;
use crate::gui::widgets::modal::Modal;
use crate::gui::widgets::package_row::{Message as RowMessage, PackageRow};
use iced::widget::{
button, column, container, horizontal_space, pick_list, radio, row, scrollable, text,
text_input, tooltip, vertical_rule, Space,
};
use iced::{alignment, Alignment, Command, Element, Length, Renderer};
#[derive(Debug, Default, Clone)]
pub struct PackageInfo {
pub i_user: usize,
pub index: usize,
pub removal: String,
}
#[derive(Debug, Clone)]
pub enum LoadingState {
DownloadingList(String),
FindingPhones(String),
LoadingPackages(String),
_UpdatingUad(String),
Ready(String),
RestoringDevice(String),
}
impl Default for LoadingState {
fn default() -> Self {
Self::FindingPhones(String::new())
}
}
#[derive(Default, Debug, Clone)]
pub struct List {
pub loading_state: LoadingState,
pub uad_lists: HashMap<String, Package>,
pub phone_packages: Vec<Vec<PackageRow>>, // packages of all users of the phone
filtered_packages: Vec<usize>, // phone_packages indexes of the selected user (= what you see on screen)
selected_packages: Vec<(usize, usize)>, // Vec of (user_index, pkg_index)
selected_package_state: Option<PackageState>,
selected_removal: Option<Removal>,
selected_list: Option<UadList>,
selected_user: Option<User>,
pub input_value: String,
description: String,
selection_modal: bool,
current_package_index: usize,
}
#[derive(Debug, Clone)]
pub enum Message {
LoadUadList(bool),
LoadPhonePackages((HashMap<String, Package>, UadListState)),
RestoringDevice(Result<CommandType, ()>),
ApplyFilters(Vec<Vec<PackageRow>>),
SearchInputChanged(String),
ToggleAllSelected(bool),
ListSelected(UadList),
UserSelected(User),
PackageStateSelected(PackageState),
RemovalSelected(Removal),
ApplyActionOnSelection,
List(usize, RowMessage),
ChangePackageState(Result<CommandType, ()>),
Nothing,
ModalHide,
ModalUserSelected(User),
ModalValidate,
}
impl List {
pub fn update(
&mut self,
settings: &mut Settings,
selected_device: &mut Phone,
list_update_state: &mut UadListState,
message: Message,
) -> Command<Message> {
let i_user = self.selected_user.unwrap_or_default().index;
match message {
Message::ModalHide => {
self.selection_modal = false;
Command::none()
}
Message::ModalValidate => {
let mut commands = vec![];
self.selected_packages.sort_unstable();
self.selected_packages.dedup();
for selection in &self.selected_packages {
commands.append(&mut build_action_pkg_commands(
&self.phone_packages,
selected_device,
&settings.device,
*selection,
));
}
self.selection_modal = false;
Command::batch(commands)
}
Message::RestoringDevice(output) => {
if let Ok(res) = output {
if let CommandType::PackageManager(p) = res {
self.loading_state = LoadingState::RestoringDevice(
self.phone_packages[i_user][p.index].name.clone(),
);
}
} else {
self.loading_state = LoadingState::RestoringDevice("Error [TODO]".to_string());
}
Command::none()
}
Message::LoadUadList(remote) => {
info!("{:-^65}", "-");
info!(
"ANDROID_SDK: {} | DEVICE: {}",
selected_device.android_sdk, selected_device.model
);
info!("{:-^65}", "-");
self.loading_state = LoadingState::DownloadingList(String::new());
Command::perform(
Self::init_apps_view(remote, selected_device.clone()),
Message::LoadPhonePackages,
)
}
Message::LoadPhonePackages(list_box) => {
let (uad_list, list_state) = list_box;
self.loading_state = LoadingState::LoadingPackages(String::new());
self.uad_lists = uad_list.clone();
*list_update_state = list_state;
Command::perform(
Self::load_packages(uad_list, selected_device.user_list.clone()),
Message::ApplyFilters,
)
}
Message::ApplyFilters(packages) => {
self.phone_packages = packages;
self.filtered_packages = (0..self.phone_packages[i_user].len()).collect();
self.selected_package_state = Some(PackageState::Enabled);
self.selected_removal = Some(Removal::Recommended);
self.selected_list = Some(UadList::All);
self.selected_user = Some(User::default());
Self::filter_package_lists(self);
self.loading_state = LoadingState::Ready(String::new());
Command::none()
}
Message::ToggleAllSelected(selected) => {
#[allow(unused_must_use)]
for i in self.filtered_packages.clone() {
if self.phone_packages[i_user][i].selected != selected {
self.update(
settings,
selected_device,
list_update_state,
Message::List(i, RowMessage::ToggleSelection(selected)),
);
}
}
Command::none()
}
Message::SearchInputChanged(letter) => {
self.input_value = letter;
Self::filter_package_lists(self);
Command::none()
}
Message::ListSelected(list) => {
self.selected_list = Some(list);
Self::filter_package_lists(self);
Command::none()
}
Message::PackageStateSelected(package_state) => {
self.selected_package_state = Some(package_state);
Self::filter_package_lists(self);
Command::none()
}
Message::RemovalSelected(removal) => {
self.selected_removal = Some(removal);
Self::filter_package_lists(self);
Command::none()
}
Message::List(i_package, row_message) => {
#[allow(unused_must_use)]
{
self.phone_packages[i_user][i_package]
.update(&row_message)
.map(move |row_message| Message::List(i_package, row_message));
}
let package = &mut self.phone_packages[i_user][i_package];
match row_message {
RowMessage::ToggleSelection(toggle) => {
if package.removal == Removal::Unsafe && !settings.general.expert_mode {
package.selected = false;
return Command::none();
}
if settings.device.multi_user_mode {
for u in selected_device.user_list.iter().filter(|&u| !u.protected) {
self.phone_packages[u.index][i_package].selected = toggle;
if toggle {
self.selected_packages.push((u.index, i_package));
}
}
if !toggle {
self.selected_packages.retain(|&x| x.1 != i_package);
}
} else {
package.selected = toggle;
if toggle {
self.selected_packages.push((i_user, i_package));
} else {
self.selected_packages
.retain(|&x| x.1 != i_package || x.0 != i_user);
}
}
Command::none()
}
RowMessage::ActionPressed => {
self.phone_packages[i_user][i_package].selected = true;
Command::batch(build_action_pkg_commands(
&self.phone_packages,
selected_device,
&settings.device,
(i_user, i_package),
))
}
RowMessage::PackagePressed => {
self.description = package.clone().description;
package.current = true;
if self.current_package_index != i_package {
self.phone_packages[i_user][self.current_package_index].current = false;
}
self.current_package_index = i_package;
Command::none()
}
}
}
Message::ApplyActionOnSelection => {
self.selection_modal = true;
Command::none()
}
Message::UserSelected(user) => {
self.selected_user = Some(user);
self.filtered_packages = (0..self.phone_packages[user.index].len()).collect();
Self::filter_package_lists(self);
Command::none()
}
Message::ChangePackageState(res) => {
if let Ok(CommandType::PackageManager(p)) = res {
let package = &mut self.phone_packages[p.i_user][p.index];
package.state = package.state.opposite(settings.device.disable_mode);
package.selected = false;
self.selected_packages
.retain(|&x| x.1 != p.index && x.0 != p.i_user);
Self::filter_package_lists(self);
}
Command::none()
}
Message::ModalUserSelected(user) => {
self.selected_user = Some(user);
self.update(
settings,
selected_device,
list_update_state,
Message::UserSelected(user),
)
}
Message::Nothing => Command::none(),
}
}
pub fn view(
&self,
settings: &Settings,
selected_device: &Phone,
) -> Element<Message, Renderer<Theme>> {
match &self.loading_state {
LoadingState::DownloadingList(_) => {
let text = "Downloading latest UAD lists from Github. Please wait...";
waiting_view(settings, text, true)
}
LoadingState::FindingPhones(_) => {
let text = "Finding connected devices...";
waiting_view(settings, text, false)
}
LoadingState::LoadingPackages(_) => {
let text = "Pulling packages from the device. Please wait...";
waiting_view(settings, text, false)
}
LoadingState::_UpdatingUad(_) => {
let text = "Updating UAD. Please wait...";
waiting_view(settings, text, false)
}
LoadingState::RestoringDevice(output) => {
let text = format!("Restoring device: {output}");
waiting_view(settings, &text, false)
}
LoadingState::Ready(_) => {
let search_packages = text_input("Search packages...", &self.input_value)
.on_input(Message::SearchInputChanged)
.padding(5);
let user_picklist = pick_list(
selected_device.user_list.clone(),
self.selected_user,
Message::UserSelected,
)
.width(85);
let divider = Space::new(Length::Fill, Length::Shrink);
let list_picklist =
pick_list(&UadList::ALL[..], self.selected_list, Message::ListSelected);
let package_state_picklist = pick_list(
&PackageState::ALL[..],
self.selected_package_state,
Message::PackageStateSelected,
);
let removal_picklist = pick_list(
&Removal::ALL[..],
self.selected_removal,
Message::RemovalSelected,
);
let control_panel = row![
search_packages,
user_picklist,
divider,
removal_picklist,
package_state_picklist,
list_picklist,
]
.width(Length::Fill)
.align_items(Alignment::Center)
.spacing(10)
.padding([0, 16, 0, 0]);
let packages =
self.filtered_packages
.iter()
.fold(column![].spacing(6), |col, i| {
col.push(
self.phone_packages[self.selected_user.unwrap().index][*i]
.view(settings, selected_device)
.map(move |msg| Message::List(*i, msg)),
)
});
let packages_scrollable = scrollable(packages)
.height(Length::FillPortion(6))
.style(style::Scrollable::Packages);
let description_scroll = scrollable(text(&self.description).width(Length::Fill))
.style(style::Scrollable::Description);
let description_panel = container(description_scroll)
.padding(6)
.height(Length::FillPortion(2))
.width(Length::Fill)
.style(style::Container::Frame);
let review_selection = if !self.selected_packages.is_empty() {
button(text(format!(
"Review selection ({})",
self.selected_packages.len()
)))
.on_press(Message::ApplyActionOnSelection)
.padding(5)
.style(style::Button::Primary)
} else {
button(text(format!(
"Review selection ({})",
self.selected_packages.len()
)))
.padding(5)
};
let select_all_btn = button("Select all")
.padding(5)
.on_press(Message::ToggleAllSelected(true))
.style(style::Button::Primary);
let unselect_all_btn = button("Unselect all")
.padding(5)
.on_press(Message::ToggleAllSelected(false))
.style(style::Button::Primary);
let action_row = row![
select_all_btn,
unselect_all_btn,
Space::new(Length::Fill, Length::Shrink),
review_selection,
]
.width(Length::Fill)
.spacing(10)
.align_items(Alignment::Center);
let unavailable = container(
column![
text("ADB is not authorized to access this user!").size(22)
.style(style::Text::Danger),
text("The most likely reason is that it is the user of your work profile (also called Secure Folder on Samsung devices). There's really no solution, other than completely disabling your work profile in your device settings.")
.style(style::Text::Commentary)
.horizontal_alignment(alignment::Horizontal::Center),
]
.spacing(6)
.align_items(Alignment::Center)
)
.padding(10)
.center_x()
.style(style::Container::BorderedFrame);
let content = if selected_device.user_list.is_empty()
|| !self.phone_packages[self.selected_user.unwrap().index].is_empty()
{
column![
control_panel,
packages_scrollable,
description_panel,
action_row,
]
.width(Length::Fill)
.spacing(10)
.align_items(Alignment::Center)
} else {
column![
control_panel,
container(unavailable).height(Length::Fill).center_y(),
]
.width(Length::Fill)
.spacing(10)
.align_items(Alignment::Center)
};
if self.selection_modal {
Modal::new(
content.padding(10),
self.apply_selection_modal(
selected_device,
settings,
&self.phone_packages[self.selected_user.unwrap().index],
),
)
.on_blur(Message::ModalHide)
.into()
} else {
container(content).height(Length::Fill).padding(10).into()
}
}
}
}
fn apply_selection_modal(
&self,
device: &Phone,
settings: &Settings,
packages: &[PackageRow],
) -> Element<Message, Renderer<Theme>> {
// (nb_to_restore, nb_to_remove)
let mut h_recap: HashMap<Removal, (u8, u8)> = HashMap::new();
for p in packages.iter().filter(|p| p.selected) {
if p.state == PackageState::Uninstalled || p.state == PackageState::Disabled {
h_recap.entry(p.removal).or_insert((0, 0)).1 += 1;
} else {
h_recap.entry(p.removal).or_insert((0, 0)).0 += 1;
}
}
let radio_btn_users = device.user_list.iter().filter(|&u| !u.protected).fold(
row![].spacing(10),
|row, user| {
row.push(
radio(
format!("{}", user.clone()),
*user,
self.selected_user,
Message::ModalUserSelected,
)
.size(23),
)
},
);
let title_ctn =
container(row![text("Review your selection").size(25)].align_items(Alignment::Center))
.width(Length::Fill)
.style(style::Container::Frame)
.padding([10, 0, 10, 0])
.center_y()
.center_x();
let users_ctn = container(radio_btn_users)
.padding(10)
.center_x()
.style(style::Container::Frame);
let explaination_ctn = container(
row![
text("The action for the selected user will be applied to all other users")
.style(style::Text::Danger),
tooltip(
text("\u{EA0C}")
.font(ICONS)
.width(17)
.horizontal_alignment(alignment::Horizontal::Center)
.style(style::Text::Commentary)
.size(17),
"Let's say you choose user 0. If a selected package on user 0\n\
is set to be uninstalled and if this same package is disabled on user 10,\n\
then the package on both users will be uninstalled.",
tooltip::Position::Top,
)
.gap(20)
.padding(10)
.size(17)
.style(style::Container::Tooltip)
]
.spacing(10),
)
.center_x()
.padding(10)
.style(style::Container::BorderedFrame);
let modal_btn_row = row![
button(text("Cancel")).on_press(Message::ModalHide),
horizontal_space(Length::Fill),
button(text("Apply")).on_press(Message::ModalValidate),
]
.padding([0, 15, 10, 10]);
let recap_view = Removal::ALL
.iter()
.filter(|&&r| r != Removal::All)
.fold(column![].spacing(6).width(Length::Fill), |col, r| {
col.push(recap(settings, &mut h_recap, *r))
});
let selected_pkgs_ctn = container(
container(
scrollable(
container(
if !self
.selected_packages
.iter()
.any(|s| s.0 == self.selected_user.unwrap().index)
{
column![text("No packages selected for this user")]
.align_items(Alignment::Center)
.width(Length::Fill)
} else {
self.selected_packages
.iter()
.filter(|s| s.0 == self.selected_user.unwrap().index)
.fold(
column![].spacing(6).width(Length::Fill),
|col, selection| {
col.push(
row![
row![text(
self.phone_packages[selection.0][selection.1]
.removal
)]
.width(100),
row![text(
self.phone_packages[selection.0][selection.1]
.uad_list
)]
.width(60),
row![text(
self.phone_packages[selection.0][selection.1]
.name
.clone()
),],
horizontal_space(Length::Fill),
row![match self.phone_packages[selection.0]
[selection.1]
.state
{
PackageState::Enabled =>
if settings.device.disable_mode {
text("Disable")
.style(style::Text::Danger)
} else {
text("Uninstall")
.style(style::Text::Danger)
},
PackageState::Disabled =>
text("Enable").style(style::Text::Ok),
PackageState::Uninstalled =>
text("Restore").style(style::Text::Ok),
PackageState::All => text("Impossible")
.style(style::Text::Danger),
},]
.width(60),
]
.width(Length::Fill)
.spacing(20),
)
},
)
},
)
.padding(10)
.width(Length::Fill),
)
.style(style::Scrollable::Description),
)
.width(Length::Fill)
.style(style::Container::Frame),
)
.width(Length::Fill)
.max_height(150)
.padding([0, 10, 0, 10]);
container(
if device.user_list.iter().filter(|&u| !u.protected).count() > 1
&& settings.device.multi_user_mode
{
column![
title_ctn,
users_ctn,
row![explaination_ctn].padding([0, 10, 0, 10]),
container(recap_view).padding(10),
selected_pkgs_ctn,
modal_btn_row,
]
.spacing(10)
.align_items(Alignment::Center)
} else if !settings.device.multi_user_mode {
column![
title_ctn,
users_ctn,
container(recap_view).padding(10),
selected_pkgs_ctn,
modal_btn_row,
]
.spacing(10)
.align_items(Alignment::Center)
} else {
column![
title_ctn,
container(recap_view).padding(10),
selected_pkgs_ctn,
modal_btn_row,
]
.spacing(10)
.align_items(Alignment::Center)
},
)
.width(800)
.height(Length::Shrink)
.max_height(700)
.style(style::Container::Background)
.into()
}
fn filter_package_lists(&mut self) {
let list_filter: UadList = self.selected_list.unwrap();
let package_filter: PackageState = self.selected_package_state.unwrap();
let removal_filter: Removal = self.selected_removal.unwrap();
self.filtered_packages = self.phone_packages[self.selected_user.unwrap().index]
.iter()
.enumerate()
.filter(|(_, p)| {
(list_filter == UadList::All || p.uad_list == list_filter)
&& (package_filter == PackageState::All || p.state == package_filter)
&& (removal_filter == Removal::All || p.removal == removal_filter)
&& (self.input_value.is_empty() || p.name.contains(&self.input_value))
})
.map(|(i, _)| i)
.collect();
}
async fn load_packages(
uad_list: HashMap<String, Package>,
user_list: Vec<User>,
) -> Vec<Vec<PackageRow>> {
let mut phone_packages = vec![];
if user_list.len() <= 1 {
phone_packages.push(fetch_packages(&uad_list, None));
} else {
phone_packages.extend(
user_list
.iter()
.map(|user| fetch_packages(&uad_list, Some(user))),
);
};
phone_packages
}
async fn init_apps_view(
remote: bool,
phone: Phone,
) -> (HashMap<String, Package>, UadListState) {
let (uad_lists, _) = load_debloat_lists(remote);
match uad_lists {
Ok(list) => {
env::set_var("ANDROID_SERIAL", phone.adb_id.clone());
if phone.adb_id.is_empty() {
error!("AppsView ready but no phone found");
}
(list, UadListState::Done)
}
Err(local_list) => {
error!("Error loading remote debloat list for the phone. Fallback to embedded (and outdated) list");
(local_list, UadListState::Failed)
}
}
}
}
fn waiting_view<'a>(
_settings: &Settings,
displayed_text: &str,
btn: bool,
) -> Element<'a, Message, Renderer<Theme>> {
let col = if btn {
let no_internet_btn = button("No internet?")
.padding(5)
.on_press(Message::LoadUadList(false))
.style(style::Button::Primary);
column![]
.spacing(10)
.align_items(Alignment::Center)
.push(text(displayed_text).size(20))
.push(no_internet_btn)
} else {
column![]
.spacing(10)
.align_items(Alignment::Center)
.push(text(displayed_text).size(20))
};
container(col)
.width(Length::Fill)
.height(Length::Fill)
.center_y()
.center_x()
.style(style::Container::default())
.into()
}
fn build_action_pkg_commands(
packages: &[Vec<PackageRow>],
device: &Phone,
settings: &DeviceSettings,
selection: (usize, usize),
) -> Vec<Command<Message>> {
let pkg = &packages[selection.0][selection.1];
let wanted_state = pkg.state.opposite(settings.disable_mode);
let mut commands = vec![];
for u in device.user_list.iter().filter(|&&u| {
!u.protected && (packages[u.index][selection.1].selected || settings.multi_user_mode)
}) {
let u_pkg = packages[u.index][selection.1].clone();
let actions = if settings.multi_user_mode {
apply_pkg_state_commands(&u_pkg.into(), wanted_state, u, device)
} else {
let wanted_state = u_pkg.state.opposite(settings.disable_mode);
apply_pkg_state_commands(&u_pkg.into(), wanted_state, u, device)
};
for (j, action) in actions.into_iter().enumerate() {
let p_info = PackageInfo {
i_user: u.index,
index: selection.1,
removal: pkg.removal.to_string(),
};
// In the end there is only one package state change
// even if we run multiple adb commands
commands.push(Command::perform(
perform_adb_commands(action, CommandType::PackageManager(p_info)),
if j == 0 {
Message::ChangePackageState
} else {
|_| Message::Nothing
},
));
}
}
commands
}
fn recap<'a>(
settings: &Settings,
recap: &mut HashMap<Removal, (u8, u8)>,
removal: Removal,
) -> Element<'a, Message, Renderer<Theme>> {
container(
row![
text(removal).size(25).width(Length::FillPortion(1)),
vertical_rule(5),
row![
if settings.device.disable_mode {
text("Disable").style(style::Text::Danger)
} else {
text("Uninstall").style(style::Text::Danger)
},
horizontal_space(Length::Fill),
text(recap.entry(removal).or_insert((0, 0)).0.to_string())
.style(style::Text::Danger)
]
.width(Length::FillPortion(1)),
vertical_rule(5),
row![
if settings.device.disable_mode {
text("Enable").style(style::Text::Ok)
} else {
text("Restore").style(style::Text::Ok)
},
horizontal_space(Length::Fill),
text(recap.entry(removal).or_insert((0, 0)).1.to_string()).style(style::Text::Ok)
]
.width(Length::FillPortion(1))
]
.spacing(20)
.padding([0, 10, 0, 0])
.width(Length::Fill)
.align_items(Alignment::Center),
)
.padding(10)
.width(Length::Fill)
.height(45)
.style(style::Container::Frame)
.into()
}

View file

@ -1,427 +0,0 @@
use crate::core::config::{BackupSettings, Config, DeviceSettings, GeneralSettings};
use crate::core::save::{
backup_phone, list_available_backup_user, list_available_backups, restore_backup, BACKUP_DIR,
};
use crate::core::sync::{get_android_sdk, perform_adb_commands, CommandType, Phone};
use crate::core::theme::Theme;
use crate::core::utils::{open_url, string_to_theme, DisplayablePath};
use crate::gui::style;
use crate::gui::views::list::PackageInfo;
use crate::gui::widgets::package_row::PackageRow;
use iced::widget::{button, checkbox, column, container, pick_list, radio, row, text, Space};
use iced::{alignment, Alignment, Command, Element, Length, Renderer};
use std::path::PathBuf;
#[derive(Debug, Clone)]
pub struct Settings {
pub general: GeneralSettings,
pub device: DeviceSettings,
}
impl Default for Settings {
fn default() -> Self {
Self {
general: Config::load_configuration_file().general,
device: DeviceSettings::default(),
}
}
}
#[derive(Debug, Clone)]
pub enum Message {
LoadDeviceSettings,
ExpertMode(bool),
DisableMode(bool),
MultiUserMode(bool),
ApplyTheme(Theme),
UrlPressed(PathBuf),
BackupSelected(DisplayablePath),
BackupDevice,
RestoreDevice,
RestoringDevice(Result<CommandType, ()>),
DeviceBackedUp(Result<(), String>),
}
impl Settings {
pub fn update(
&mut self,
phone: &Phone,
packages: &[Vec<PackageRow>],
nb_running_async_adb_commands: &mut u32,
msg: Message,
) -> Command<Message> {
match msg {
Message::ExpertMode(toggled) => {
self.general.expert_mode = toggled;
debug!("Config change: {:?}", self);
Config::save_changes(self, &phone.adb_id);
Command::none()
}
Message::DisableMode(toggled) => {
if phone.android_sdk >= 23 {
self.device.disable_mode = toggled;
debug!("Config change: {:?}", self);
Config::save_changes(self, &phone.adb_id);
}
Command::none()
}
Message::MultiUserMode(toggled) => {
self.device.multi_user_mode = toggled;
debug!("Config change: {:?}", self);
Config::save_changes(self, &phone.adb_id);
Command::none()
}
Message::ApplyTheme(theme) => {
self.general.theme = theme.to_string();
debug!("Config change: {:?}", self);
Config::save_changes(self, &phone.adb_id);
Command::none()
}
Message::UrlPressed(url) => {
open_url(url);
Command::none()
}
Message::LoadDeviceSettings => {
let backups = list_available_backups(&BACKUP_DIR.join(phone.adb_id.clone()));
match Config::load_configuration_file()
.devices
.iter()
.find(|d| d.device_id == phone.adb_id)
{
Some(device) => {
self.device = device.clone();
self.device.backup = BackupSettings {
backups: backups.clone(),
selected: backups.first().cloned(),
users: phone.user_list.clone(),
selected_user: phone.user_list.first().copied(),
backup_state: String::new(),
};
}
None => {
self.device = DeviceSettings {
device_id: phone.adb_id.clone(),
multi_user_mode: phone.android_sdk > 21,
disable_mode: false,
backup: BackupSettings {
backups: backups.clone(),
selected: backups.first().cloned(),
users: phone.user_list.clone(),
selected_user: phone.user_list.first().copied(),
backup_state: String::new(),
},
}
}
};
Command::none()
}
Message::BackupSelected(d_path) => {
self.device.backup.selected = Some(d_path.clone());
self.device.backup.users = list_available_backup_user(d_path);
Command::none()
}
Message::BackupDevice => Command::perform(
backup_phone(
phone.user_list.clone(),
self.device.device_id.clone(),
packages.to_vec(),
),
Message::DeviceBackedUp,
),
Message::DeviceBackedUp(_) => {
info!("[BACKUP] Backup successfully created");
self.device.backup.backups =
list_available_backups(&BACKUP_DIR.join(phone.adb_id.clone()));
self.device.backup.selected = self.device.backup.backups.first().cloned();
Command::none()
}
Message::RestoreDevice => match restore_backup(phone, packages, &self.device) {
Ok(r_packages) => {
let mut commands = vec![];
*nb_running_async_adb_commands = 0;
for p in &r_packages {
let p_info = PackageInfo {
i_user: 0,
index: p.index,
removal: "RESTORE".to_string(),
};
for command in p.commands.clone() {
*nb_running_async_adb_commands += 1;
commands.push(Command::perform(
perform_adb_commands(
command,
CommandType::PackageManager(p_info.clone()),
),
Message::RestoringDevice,
));
}
}
if r_packages.is_empty() {
if get_android_sdk() == 0 {
self.device.backup.backup_state = "Device is not connected".to_string();
} else {
self.device.backup.backup_state =
"Device state is already restored".to_string();
}
}
info!(
"[RESTORE] Restoring backup {}",
self.device.backup.selected.as_ref().unwrap()
);
Command::batch(commands)
}
Err(e) => {
self.device.backup.backup_state = e.to_string();
error!("{} - {}", self.device.backup.selected.as_ref().unwrap(), e);
Command::none()
}
},
// Trigger an action in mod.rs (Message::SettingsAction(msg))
Message::RestoringDevice(_) => Command::none(),
}
}
pub fn view(&self, phone: &Phone) -> Element<Message, Renderer<Theme>> {
let radio_btn_theme = Theme::ALL
.iter()
.fold(row![].spacing(10), |column, option| {
column.push(
radio(
format!("{}", option.clone()),
*option,
Some(string_to_theme(&self.general.theme)),
Message::ApplyTheme,
)
.size(23),
)
});
let theme_ctn = container(radio_btn_theme)
.padding(10)
.width(Length::Fill)
.height(Length::Shrink)
.style(style::Container::Frame);
let expert_mode_checkbox = checkbox(
"Allow to uninstall packages marked as \"unsafe\" (I KNOW WHAT I AM DOING)",
self.general.expert_mode,
Message::ExpertMode,
)
.style(style::CheckBox::SettingsEnabled);
let expert_mode_descr =
text("Most of unsafe packages are known to bootloop the device if removed.")
.style(style::Text::Commentary)
.size(15);
let general_ctn = container(column![expert_mode_checkbox, expert_mode_descr].spacing(10))
.padding(10)
.width(Length::Fill)
.height(Length::Shrink)
.style(style::Container::Frame);
let warning_ctn = container(
row![
text("The following settings only affect the currently selected device :")
.style(style::Text::Danger),
text(phone.model.clone()),
Space::new(Length::Fill, Length::Shrink),
text(phone.adb_id.clone()).style(style::Text::Commentary)
]
.spacing(7),
)
.padding(10)
.width(Length::Fill)
.style(style::Container::BorderedFrame);
let multi_user_mode_descr = row![
text("This will not affect the following protected work profile users: ")
.size(15)
.style(style::Text::Commentary),
text(
phone
.user_list
.iter()
.filter(|&u| u.protected)
.map(|u| u.id.to_string())
.collect::<Vec<String>>()
.join(", ")
)
.size(15)
.style(style::Text::Danger)
];
let multi_user_mode_checkbox = checkbox(
"Affect all the users of the device (not only the selected user)",
self.device.multi_user_mode,
Message::MultiUserMode,
)
.style(style::CheckBox::SettingsEnabled);
let disable_checkbox_style = if phone.android_sdk >= 23 {
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")
.style(style::Text::Commentary)
.size(15);
let unavailable_btn = button(text("Unavailable").size(13))
.on_press(Message::UrlPressed(PathBuf::from(
"https://github.com/Universal-Debloater-Alliance/universal-android-debloater/wiki/FAQ#\
why-is-the-disable-mode-setting-not-available-for-my-device",
)))
.height(22)
.style(style::Button::Unavailable);
// Disabling package without root isn't really possible before Android Oreo (8.0)
// see https://github.com/Universal-Debloater-Alliance/universal-android-debloater/wiki/ADB-reference
let disable_mode_checkbox = checkbox(
"Clear and disable packages instead of uninstalling them",
self.device.disable_mode,
Message::DisableMode,
)
.style(disable_checkbox_style);
let disable_setting_row = if phone.android_sdk >= 23 {
row![
disable_mode_checkbox,
Space::new(Length::Fill, Length::Shrink),
]
.width(Length::Fill)
} else {
row![
disable_mode_checkbox,
Space::new(Length::Fill, Length::Shrink),
unavailable_btn,
]
.width(Length::Fill)
};
let device_specific_ctn = container(
column![
multi_user_mode_checkbox,
multi_user_mode_descr,
disable_setting_row,
disable_mode_descr,
]
.spacing(10),
)
.padding(10)
.width(Length::Fill)
.height(Length::Shrink)
.style(style::Container::Frame);
let backup_pick_list = pick_list(
self.device.backup.backups.clone(),
self.device.backup.selected.clone(),
Message::BackupSelected,
)
.padding(6);
let backup_btn = button(text("Backup").horizontal_alignment(alignment::Horizontal::Center))
.padding(5)
.on_press(Message::BackupDevice)
.style(style::Button::Primary)
.width(77);
let restore_btn = |enabled| {
if enabled {
button(text("Restore").horizontal_alignment(alignment::Horizontal::Center))
.padding(5)
.on_press(Message::RestoreDevice)
.width(77)
} else {
button(text("No backup").horizontal_alignment(alignment::Horizontal::Center))
.padding(5)
.width(77)
}
};
let locate_backup_btn = if self.device.backup.backups.is_empty() {
button("Open backup directory")
.padding(5)
.style(style::Button::Primary)
} else {
button("Open backup directory")
.on_press(Message::UrlPressed(BACKUP_DIR.join(phone.adb_id.clone())))
.padding(5)
.style(style::Button::Primary)
};
let backup_row = row![
backup_btn,
"Backup the current state of the phone",
Space::new(Length::Fill, Length::Shrink),
locate_backup_btn,
]
.spacing(10)
.align_items(Alignment::Center);
let restore_row = if self.device.backup.backups.is_empty() {
row![restore_btn(false), "Restore the state of the device",]
.spacing(10)
.align_items(Alignment::Center)
} else {
row![
restore_btn(true),
"Restore the state of the device",
Space::new(Length::Fill, Length::Shrink),
text(self.device.backup.backup_state.clone()).style(style::Text::Danger),
backup_pick_list,
]
.spacing(10)
.align_items(Alignment::Center)
};
let backup_restore_ctn = container(column![backup_row, restore_row].spacing(10))
.padding(10)
.width(Length::Fill)
.height(Length::Shrink)
.style(style::Container::Frame);
let no_device_ctn = || {
container(text("No device detected").style(style::Text::Danger))
.padding(10)
.width(Length::Fill)
.style(style::Container::BorderedFrame)
};
let content = if phone.adb_id.clone().is_empty() {
column![
text("Theme").size(25),
theme_ctn,
text("General").size(25),
general_ctn,
text("Current device").size(25),
no_device_ctn(),
text("Backup / Restore").size(25),
no_device_ctn(),
]
.width(Length::Fill)
.spacing(20)
} else {
column![
text("Theme").size(25),
theme_ctn,
text("General").size(25),
general_ctn,
text("Current device").size(25),
warning_ctn,
device_specific_ctn,
backup_restore_ctn,
]
.width(Length::Fill)
.spacing(20)
};
container(content)
.padding(10)
.width(Length::Fill)
.height(Length::Fill)
.into()
}
}

View file

@ -1,113 +0,0 @@
pub use crate::core::sync::Phone;
use crate::core::theme::Theme;
use crate::core::update::{SelfUpdateState, SelfUpdateStatus};
pub use crate::gui::views::about::Message as AboutMessage;
pub use crate::gui::views::list::{List as AppsView, LoadingState as ListLoadingState};
use crate::gui::{style, Message};
use iced::widget::{button, container, pick_list, row, text, Space, Text};
use iced::{alignment, Alignment, Element, Font, Length, Renderer};
pub const ICONS: Font = Font::External {
name: "Icons",
bytes: include_bytes!("../../../resources/assets/icons.ttf"),
};
pub fn nav_menu<'a>(
device_list: &'a Vec<Phone>,
selected_device: Option<Phone>,
apps_view: &AppsView,
self_update_state: &SelfUpdateState,
) -> Element<'a, Message, Renderer<Theme>> {
let apps_refresh_btn = button(
Text::new("\u{E900}")
.font(ICONS)
.width(17)
.horizontal_alignment(alignment::Horizontal::Center)
.size(17),
)
.on_press(Message::RefreshButtonPressed)
.padding(5)
.style(style::Button::Refresh);
let reboot_btn = button("Reboot")
.on_press(Message::RebootButtonPressed)
.padding(5)
.style(style::Button::Refresh);
#[allow(clippy::option_if_let_else)]
let uad_version_text = if let Some(r) = &self_update_state.latest_release {
if self_update_state.status == SelfUpdateStatus::Updating {
Text::new("Updating please wait...")
} else {
Text::new(format!(
"New UAD version available {} -> {}",
env!("CARGO_PKG_VERSION"),
r.tag_name
))
}
} else {
Text::new(env!("CARGO_PKG_VERSION"))
};
let apps_btn = if self_update_state.latest_release.is_some() {
button("Update")
.on_press(Message::AboutAction(AboutMessage::DoSelfUpdate))
.padding(5)
.style(style::Button::SelfUpdate)
} else {
button("Apps")
.on_press(Message::AppsPress)
.padding(5)
.style(style::Button::Primary)
};
let about_btn = button("About")
.on_press(Message::AboutPressed)
.padding(5)
.style(style::Button::Primary);
let settings_btn = button("Settings")
.on_press(Message::SettingsPressed)
.padding(5)
.style(style::Button::Primary);
let device_list_text = match apps_view.loading_state {
ListLoadingState::FindingPhones(_) => text("finding connected phone..."),
_ => text("no devices/emulators found"),
};
let row = match selected_device {
Some(phone) => row![
apps_refresh_btn,
reboot_btn,
pick_list(device_list, Some(phone), Message::DeviceSelected,),
Space::new(Length::Fill, Length::Shrink),
uad_version_text,
apps_btn,
about_btn,
settings_btn,
]
.width(Length::Fill)
.align_items(Alignment::Center)
.spacing(10),
None => row![
reboot_btn,
apps_refresh_btn,
device_list_text,
Space::new(Length::Fill, Length::Shrink),
uad_version_text,
apps_btn,
about_btn,
settings_btn,
]
.width(Length::Fill)
.align_items(Alignment::Center)
.spacing(10),
};
container(row)
.width(Length::Fill)
.padding(10)
.style(style::Container::Frame)
.into()
}

View file

@ -1,75 +0,0 @@
#![windows_subsystem = "windows"]
#[macro_use]
extern crate log;
use crate::core::utils::setup_uad_dir;
use fern::{
colors::{Color, ColoredLevelConfig},
FormatCallback,
};
use log::Record;
use static_init::dynamic;
use std::path::PathBuf;
use std::{fmt::Arguments, fs::OpenOptions};
mod core;
mod gui;
#[dynamic]
static CONFIG_DIR: PathBuf = setup_uad_dir(dirs::config_dir());
#[dynamic]
static CACHE_DIR: PathBuf = setup_uad_dir(dirs::cache_dir());
fn main() -> iced::Result {
setup_logger().expect("setup logging");
gui::UadGui::start()
}
pub fn setup_logger() -> Result<(), fern::InitError> {
let colors = ColoredLevelConfig::new().info(Color::Green);
let make_formatter = |use_colors: bool| {
move |out: FormatCallback, message: &Arguments, record: &Record| {
out.finish(format_args!(
"{} {} [{}:{}] {}",
chrono::Local::now().format("%Y-%m-%d %H:%M:%S"),
if use_colors {
format!("{:5}", colors.color(record.level()))
} else {
format!("{:5}", record.level().to_string())
},
record.file().unwrap_or("?"),
record.line().map(|l| l.to_string()).unwrap_or_default(),
message
));
}
};
let default_log_level = log::LevelFilter::Warn;
let log_file = OpenOptions::new()
.write(true)
.create(true)
.append(true)
.truncate(false)
.open(CACHE_DIR.join(format!("UAD_{}.log", chrono::Local::now().format("%Y%m%d"))))?;
let file_dispatcher = fern::Dispatch::new()
.format(make_formatter(false))
.level(default_log_level)
.level_for("uad_gui", log::LevelFilter::Debug)
.chain(log_file);
let stdout_dispatcher = fern::Dispatch::new()
.format(make_formatter(true))
.level(default_log_level)
.level_for("uad_gui", log::LevelFilter::Warn)
.chain(std::io::stdout());
fern::Dispatch::new()
.chain(stdout_dispatcher)
.chain(file_dispatcher)
.apply()?;
Ok(())
}