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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions v2/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,15 @@ this file and shows the newest few sections, dated, from its version button.

### Fixed

- **Disabling the stock launcher from the App List or Optimize left Setup Wraith on**
([#157](https://github.com/bryanroscoe/shield_optimizer/issues/157)). Every way of
disabling Google TV's stock launcher now turns Setup Wraith off with it, once another
launcher holds Home, using the same checks as Disable stock launcher. If no other
launcher holds Home yet, Setup Wraith is left on and the app says how to finish.
- **"Enable & set default" on the stock launcher left Setup Wraith off**
([#158](https://github.com/bryanroscoe/shield_optimizer/issues/158)). Turning the stock
launcher back on by any route now turns Setup Wraith back on too, on desktop and mobile.

- **Disabling the stock launcher on Google TV now turns off Setup Wraith too, so
it can't take the Home button back** (#122). Google TV's setup helper
(`com.google.android.tungsten.setupwraith`) declares a Home screen, and with
Expand Down
119 changes: 115 additions & 4 deletions v2/crates/core/src/commands/apps.rs
Original file line number Diff line number Diff line change
Expand Up @@ -449,12 +449,95 @@ pub(crate) async fn disable_package_impl(
return Ok(refusal);
}
state.require_pro(Feature::CuratedDebloat)?;
run(
// A stock launcher with a paired setup helper (Google TV's Setup Wraith):
// read the Home apps before disabling it, so the helper can follow (#157).
let pairs_helper = !super::loader::launchers()
.disable_with_for(package)
.is_empty();
let inventory = if pairs_helper {
let adb = state.adb_snapshot().await;
match adb.shell(serial, super::launcher::HOME_HANDLER_QUERY).await {
Ok(out) if out.success() && !out.shell_reported_failure() => {
Some(super::launcher::parse_home_handler_packages(&out.stdout))
.filter(|h| !h.is_empty())
}
_ => None,
}
} else {
None
};
let outcome = run(
state,
serial,
&format!("pm disable-user --user 0 {package}"),
)
.await
.await;
if !pairs_helper {
return outcome;
}
// An errored or failure-marked disable may still have landed (the
// takeover path assumes the same), and stock off with its helper on is
// the unsafe state, so ask the device rather than trust the reply.
let landed = match &outcome {
Ok(r) if r.ok => true,
_ => {
let adb = state.adb_snapshot().await;
matches!(
adb.shell(serial, &format!("pm list packages -d {package}")).await,
Ok(out) if out.success()
&& out.stdout.lines().any(|l| l.trim() == format!("package:{package}"))
)
}
};
let mut result = match outcome {
Ok(r) if r.ok => r,
Ok(r) if landed => ActionResult {
ok: true,
message: r.message,
},
Err(_) if landed => ActionResult {
ok: true,
message: format!("{package} was disabled (the device's reply was lost)."),
},
other => return other,
};
if result.ok {
let adb = state.adb_snapshot().await;
let mut diagnostics = Vec::new();
use super::launcher::PairedHelperOutcome as Outcome;
match super::launcher::settle_paired_helpers_after_stock_disable(
&*adb,
serial,
package,
inventory.as_deref(),
&mut diagnostics,
)
Comment on lines +508 to +514

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Route snapshot stock disables through helper settlement

When applying a snapshot whose disabled_packages contains Google TV Home while Setup Wraith is enabled—such as a snapshot captured before this fix—apply_snapshot still calls the direct disable_from_plan loop at snapshot.rs:348-370, bypassing this new settlement logic. If the current Home app already matches the snapshot, launcher_to_set is None, so nothing later disables the helper; stock is turned off while Setup Wraith remains able to capture Home. Route snapshot stock-launcher disables through the paired-helper safety flow as well.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Fixed in c8a9118.

.await
{
Outcome::Untouched => {}
Outcome::Disabled { target } => result.message.push_str(&format!(
" Google TV's setup helper (Setup Wraith) was turned off too, so {target} keeps the Home button."
)),
Outcome::RolledBack { reason } => {
result.ok = false;
result.message = format!(
"Couldn't turn off Google TV's setup helper after disabling {package}: {reason}."
);
}
// Reported as not-ok so every caller shows it: a success toast
// would hide that the helper can still take the Home button.
Outcome::LeftOn => {
result.ok = false;
result.message = format!(
Comment on lines +527 to +531

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve the landed stock-disable state on partial outcomes

When another launcher is installed but Android still resolves Home to Setup Wraith after pm disable succeeds, LeftOn is returned after the stock launcher has actually been disabled. Marking that outcome ok = false makes existing callers treat the mutation as rolled back: mobile Apps restores its optimistic row to enabled at v2/mobile/src/screens/Apps.svelte:437-439, while the desktop App List returns before updating or invalidating state at +page.svelte:1049-1053. The screens consequently contradict the TV precisely in this recovery scenario; represent the warning separately from whether the package-state change landed, or force callers to reload the actual state.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Fixed in fea28ed.

Comment on lines +529 to +531

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Refresh launcher screens after a landed partial disable

When stock is disabled but no replacement currently holds Home, LeftOn deliberately returns ok = false after the disable has landed. Fresh evidence beyond the earlier partial-outcome fix is that both launcher-specific callers still reload only on success: mobile Launcher.svelte:152-157 and desktop +page.svelte:1542-1550. Disabling stock from either Launcher screen therefore leaves the row shown as enabled until a manual refresh, despite the warning saying it was disabled; these callers should re-read state on this partial outcome too.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Fixed in c8a9118.

"{package} was disabled, but Google TV's setup helper (Setup Wraith) is still \
on and can take the Home button. Set another launcher as Home, then use Turn \
it off on the Launcher tab."
Comment on lines +530 to +534

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Preserve partial-disable guidance in mobile Optimize

When this branch reports that stock was actually disabled but Setup Wraith remains able to capture Home, the inspected mobile Optimize flow still discards result.message: v2/mobile/src/screens/Optimize.svelte:569 records only the app name, and lines 624-626 show only a generic failure count. Fresh evidence after the claimed warning fix is therefore that users running this action through mobile Optimize are still not told that the package state changed or that they must set another launcher and use Turn it off.

Useful? React with 👍 / 👎.

);
}
}
tracing::info!(serial, package, diagnostics = ?diagnostics, "stock disable: paired helper");
}
Ok(result)
}

/// `Some(refusal)` when disabling `package` would leave the device without an
Expand Down Expand Up @@ -490,10 +573,38 @@ pub async fn enable_package(
serial: String,
package: String,
) -> Result<ActionResult, String> {
if let Some(rejection) = reject_invalid_package(&package) {
enable_package_impl(&state, &serial, &package).await
}

pub(crate) async fn enable_package_impl(
state: &AppState,
serial: &str,
package: &str,
) -> Result<ActionResult, String> {
if let Some(rejection) = reject_invalid_package(package) {
return Ok(rejection);
}
run(&state, &serial, &format!("pm enable {package}")).await
let mut result = run(state, serial, &format!("pm enable {package}")).await?;
// App List and Optimize Restore bring a disabled stock launcher back
// through here, so its paired setup helper (Setup Wraith) follows (#158).
if result.ok
&& !super::loader::launchers()
.disable_with_for(package)
.is_empty()
Comment on lines +588 to +593

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Route Advanced stock enables through paired restoration

This restoration hook only covers enable_package_impl, but the desktop Advanced picker includes every installed package and calls set_home_any_impl, which issues its own direct pm enable at launcher.rs:244. Selecting a disabled Google TV Home entry there therefore re-enables stock and can make it Home while leaving Setup Wraith disabled, despite the new any-route behavior. Reuse the paired-helper restoration after that enable succeeds.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Fixed in 64cff76, with tests.

{
let adb = state.adb_snapshot().await;
let mut diagnostics = Vec::new();
if let Some(warning) =
super::launcher::reenable_paired_helpers(&*adb, serial, package, &mut diagnostics).await
{
// Not-ok so Optimize and the App List show it rather than a plain
// "Enabled": stock is back, the helper is not.
result.ok = false;
result.message = format!("{package} was enabled. {warning}");
Comment on lines +600 to +603

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Resync package state after partial stock enables

When pm enable successfully turns stock back on but restoring Setup Wraith fails, this changes the result to ok = false even though the stock package state already changed. Fresh evidence after the warning-propagation fix is that mobile Apps reverts its optimistic row to disabled (Apps.svelte:298-303), while the desktop App List and Launcher return without refreshing (+page.svelte:1102-1109 and 1427-1430), leaving their rows inconsistent with the TV and even saying stock could not be enabled. Return mutation state separately or make every not-ok caller reload the device.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Fixed in c8a9118.

}
tracing::info!(serial, package, diagnostics = ?diagnostics, "stock enable: paired helper");
}
Ok(result)
}

/// `trim_caches` — ask the package manager to clear app caches device-wide.
Expand Down
Loading
Loading