dotnet / dotnet/android

Add AdbRunner app management APIs (install/uninstall/launch/force-stop/list-packages)

Open
#12,084 0 comments 0 reactions 0 assignees View on GitHub
android-tools needs-triage
Dominant language
C#
Stars
2.1k
Forks
579
Avg merge
1d 19h
Merged PRs (30d)
252

Description

## Summary

Add app management APIs to `Xamarin.Android.Tools.AdbRunner` so the MAUI DevTools CLI can install, uninstall, launch, and force-stop Android apps on devices/emulators without consumers shelling out to `adb install` / `pm` / `am`.

## Context

`AdbRunner` already exposes `ListDevicesAsync`, `WaitForDeviceAsync`, `StopEmulatorAsync`, `GetShellPropertyAsync`, `RunShellCommandAsync`, and (via dotnet/android-tools#305) reverse-port management. The next gap is the app lifecycle, which both the VS Code MAUI extension's ServiceHub and the MAUI DevTools CLI currently implement independently. See [maui-labs#197](https://github.com/dotnet/maui-labs/issues/197) for the full audit.

## Proposed API

```csharp
namespace Xamarin.Android.Tools;

public partial class AdbRunner
{
/// adb -s install [-r] [-g]
public virtual Task InstallPackageAsync(
string serial,
string apkPath,
bool replaceExisting = true,
bool grantRuntimePermissions = false,
CancellationToken cancellationToken = default);

/// adb -s uninstall [-k]
public virtual Task UninstallPackageAsync(
string serial,
string packageName,
bool keepData = false,
CancellationToken cancellationToken = default);

/// adb -s shell am start -n /
/// If activity is null, resolves the launcher activity via cmd package resolve-activity.
public virtual Task LaunchAppAsync(
string serial,
string packageName,
string? activity = null,
IReadOnlyDictionary? extras = null,
CancellationToken cancellationToken = default);

/// adb -s shell am force-stop
public virtual Task ForceStopAsync(
string serial,
string packageName,
CancellationToken cancellationToken = default);

/// adb -s shell pm list packages [-3] [-s] [filter]
public virtual Task> ListPackagesAsync(
string serial,
PackageFilter filter = PackageFilter.All,
string? namePattern = null,
CancellationToken cancellationToken = default);
}

public record AdbAppInstallResult(
bool Success,
string? PackageName,
string? ErrorCode, // INSTALL_FAILED_VERSION_DOWNGRADE etc.
string Stdout,
string Stderr);

public record AdbAppOperationResult(bool Success, string Stdout, string Stderr);

public enum PackageFilter { All, ThirdParty, System, Disabled, Enabled }
```

Notes:
- `InstallPackageAsync` should parse the `INSTALL_FAILED_*` error codes that `pm install` returns and surface them in `ErrorCode` so callers can map to typed errors (the MAUI DevTools CLI maps these to `E2xxx` codes).
- `LaunchAppAsync` activity resolution: when `activity == null`, run `cmd package resolve-activity --components ` and use the `name=...` line.

## Consumer

- **MAUI DevTools CLI** ([dotnet/maui-labs](https://github.com/dotnet/maui-labs)) — new subcommands under `maui android device`: `install`, `uninstall`, `launch`, `stop`, `list`. See [maui-labs#197](https://github.com/dotnet/maui-labs/issues/197) audit (these replace raw `adb install` / `am start` / `am force-stop` fallbacks in the DevFlow skills).
- **VS Code MAUI extension** ServiceHub → CLI migration. Today `MauiAndroidPlatform.ts` calls `AndroidDeviceManager.installApp()` / `launchApp()` / `forceStopApp()`.
- **DevFlow integration tests** that boot an emulator, install the sample APK, launch, and tear down.

## Related

- dotnet/android#12071 — Add ADB wrapper (parent issue; this extends `AdbRunner`)
- dotnet/android-tools#303 / dotnet/android-tools#305 — ADB reverse port forwarding (pattern reference for ServiceHub-equivalent APIs)
- dotnet/android#12074 — ADB push/pull (sibling file-ops feature)
- maui-labs dotnet/android-tools#197 — DevFlow skill audit, consumer follow-up

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.