fix: UAD crash when interacting with work profiles (#448)

On recent Android devices, you can't interact with the user of the work profile. Any adb commands involving this user will fail with a `Shell does not have permission to access user ${user}.`

UAD was wrongly assuming stuff and tried to access non-existent data, thus causing a crash.
This commit is contained in:
w1nst0n 2022-11-20 01:12:04 +00:00 committed by GitHub
commit 5ea61774cb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 25 additions and 15 deletions

View file

@ -225,6 +225,9 @@ pub fn apply_pkg_state_commands(
_ => vec![],
};
request_builder(commands, &package.name, &[*selected_user])
.iter()
.map(|(_, command)| command.clone())
.collect()
}
pub fn action_handler(
@ -232,7 +235,7 @@ pub fn action_handler(
package: &CorePackage,
phone: &Phone,
settings: &DeviceSettings,
) -> Vec<String> {
) -> Vec<(Option<usize>, String)> {
// https://github.com/0x192/universal-android-debloater/wiki/ADB-reference
// ALWAYS PUT THE COMMAND THAT CHANGES THE PACKAGE STATE FIRST!
let commands = match package.state {
@ -275,20 +278,24 @@ pub fn action_handler(
}
}
pub fn request_builder(commands: Vec<&str>, package: &str, users: &[User]) -> Vec<String> {
pub fn request_builder(
commands: Vec<&str>,
package: &str,
users: &[User],
) -> Vec<(Option<usize>, String)> {
if !users.is_empty() {
users
.iter()
.flat_map(|u| {
commands
.iter()
.map(|c| format!("{} --user {} {}", c, u.id, package))
.map(|c| (Some(u.index), format!("{} --user {} {}", c, u.id, package)))
})
.collect()
} else {
commands
.iter()
.map(|c| format!("{} {}", c, package))
.map(|c| (None, format!("{} {}", c, package)))
.collect()
}
}

View file

@ -25,6 +25,7 @@ pub struct Selection {
#[derive(Debug, Default, Clone)]
pub struct PackageInfo {
pub i_user: Option<usize>,
pub index: usize,
pub removal: String,
}
@ -225,8 +226,9 @@ impl List {
&settings.device,
);
for (i, action) in actions.into_iter().enumerate() {
for (i, (i_user, action)) in actions.into_iter().enumerate() {
let p_info = PackageInfo {
i_user,
index: i_package,
removal: package.removal.to_string(),
};
@ -277,10 +279,12 @@ impl List {
&settings.device,
);
for (j, action) in actions.into_iter().enumerate() {
let package = &mut self.phone_packages[i_user][i];
for (j, (i_user, action)) in actions.into_iter().enumerate() {
let p_info = PackageInfo {
i_user,
index: i,
removal: self.phone_packages[i_user][i].removal.to_string(),
removal: package.removal.to_string(),
};
// Only the first command can change the package state
commands.push(Command::perform(
@ -312,17 +316,15 @@ impl List {
let package = &mut self.phone_packages[i_user][p.index];
update_selection_count(&mut self.selection, package.state, false);
if !settings.device.multi_user_mode {
if !settings.device.multi_user_mode || p.i_user.is_none() {
package.state = package.state.opposite(settings.device.disable_mode);
package.selected = false;
} else {
for u in &selected_device.user_list {
self.phone_packages[u.index][p.index].state = self.phone_packages
[u.index][p.index]
.state
.opposite(settings.device.disable_mode);
self.phone_packages[u.index][p.index].selected = false;
}
self.phone_packages[p.i_user.unwrap()][p.index].state = self.phone_packages
[p.i_user.unwrap()][p.index]
.state
.opposite(settings.device.disable_mode);
self.phone_packages[p.i_user.unwrap()][p.index].selected = false;
}
self.selection
.selected_packages

View file

@ -142,6 +142,7 @@ impl Settings {
*nb_running_async_adb_commands = 0;
for p in &r_packages {
let p_info = PackageInfo {
i_user: None,
index: p.index,
removal: "RESTORE".to_string(),
};