Skip to content

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

@rmarinho

Description

@rmarinho

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 #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 for the full audit.

Proposed API

namespace Xamarin.Android.Tools;

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

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

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

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

    /// adb -s <serial> shell pm list packages [-3] [-s] [filter]
    public virtual Task<IReadOnlyList<string>> 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 <package> and use the name=... line.

Consumer

  • MAUI DevTools CLI (dotnet/maui-labs) — new subcommands under maui android device: install, uninstall, launch, stop, list. See maui-labs#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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions