/// <summary> /// Gets the environment variables currently defined on a device. /// </summary> /// <param name="client"> /// The connection to the adb server. /// </param> /// <param name="device"> /// The device for which to list the environment variables. /// </param> /// <returns> /// A dictionary containing the environment variables of the device, and their values. /// </returns> public static Dictionary <string, string> GetEnvironmentVariables(this IAdbClient client, DeviceData device) { var receiver = new EnvironmentVariablesReceiver(); client.ExecuteRemoteCommand(EnvironmentVariablesReceiver.PrintEnvCommand, device, receiver); return(receiver.EnvironmentVariables); }
/// <summary> /// Initializes a new instance of the <see cref="PackageManager"/> class. /// </summary> /// <param name="client"> /// The <see cref="IAdbClient"/> to use to communicate with the Android Debug Bridge. /// </param> /// <param name="device"> /// The device on which to look for packages. /// </param> /// <param name="thirdPartyOnly"> /// <see langword="true"/> to only indicate third party applications; /// <see langword="false"/> to also include built-in applications. /// </param> /// <param name="syncServiceFactory"> /// A function which returns a new instance of a class that implements the /// <see cref="ISyncService"/> interface, that can be used to transfer files to and from /// a given device. /// </param> /// <param name="skipInit"> /// A value indicating whether to skip the initial refresh of the package list or not. Used mainly by unit tests. /// </param> /// <param name="logger"> /// The logger to use when logging. /// </param> public PackageManager(IAdbClient client, DeviceData device, bool thirdPartyOnly = false, Func <IAdbClient, DeviceData, ISyncService> syncServiceFactory = null, bool skipInit = false, ILogger <PackageManager> logger = null) { if (device == null) { throw new ArgumentNullException(nameof(device)); } this.Device = device; this.Packages = new Dictionary <string, string>(); this.ThirdPartyOnly = thirdPartyOnly; this.client = client ?? throw new ArgumentNullException(nameof(client)); if (syncServiceFactory == null) { this.syncServiceFactory = Factories.SyncServiceFactory; } else { this.syncServiceFactory = syncServiceFactory; } if (!skipInit) { this.RefreshPackages(); } this.logger = logger ?? NullLogger <PackageManager> .Instance; }
/// <summary> /// Gets the file statistics of a given file. /// </summary> /// <param name="client"> /// The <see cref="IAdbClient"/> to use when executing the command. /// </param> /// <param name="device"> /// The device on which to look for the file. /// </param> /// <param name="path"> /// The path to the file. /// </param> /// <returns> /// A <see cref="FileStatistics"/> object that represents the file. /// </returns> public static FileStatistics Stat(this IAdbClient client, DeviceData device, string path) { using (ISyncService service = Factories.SyncServiceFactory(client, device)) { return(service.Stat(path)); } }
/// <summary> /// Gets the properties of a device. /// </summary> /// <param name="client"> /// The connection to the adb server. /// </param> /// <param name="device"> /// The device for which to list the properties. /// </param> /// <returns> /// A dictionary containing the properties of the device, and their values. /// </returns> public static Dictionary <string, string> GetProperties(this IAdbClient client, DeviceData device) { var receiver = new GetPropReceiver(); client.ExecuteRemoteCommand(GetPropReceiver.GetpropCommand, device, receiver); return(receiver.Properties); }
public VirtualDrive(DeviceData device, IAdbClient client, char letter) { AndroidDevice = device; Label = device.Serial; DriveLetter = letter; Sync = new SyncService(client, device); }
/// <summary> /// Initializes a new instance of the <see cref="PackageManager"/> class. /// </summary> /// <param name="device"> /// The device on which to look for packages. /// </param> /// <param name="thirdPartyOnly"> /// <see langword="true"/> to only indicate third party applications; /// <see langword="false"/> to also include built-in applications. /// </param> /// <param name="client"> /// The <see cref="IAdbClient"/> to use to communicate with the Android Debug Bridge. /// </param> /// <param name="syncServiceFactory"> /// A function which returns a new instance of a class that implements the /// <see cref="ISyncService"/> interface, that can be used to transfer files to and from /// a given device. /// </param> /// <param name="skipInit"> /// A value indicating whether to skip the initial refresh of the package list or not. Used mainly by unit tests. /// </param> public PackageManager(DeviceData device, bool thirdPartyOnly = false, IAdbClient client = null, Func <DeviceData, ISyncService> syncServiceFactory = null, bool skipInit = false) { if (device == null) { throw new ArgumentNullException(nameof(device)); } this.Device = device; this.Packages = new Dictionary <string, string>(); this.ThirdPartyOnly = thirdPartyOnly; // Default to AdbClient.Instance if (client == null) { this.client = AdbClient.Instance; } else { this.client = client; } if (syncServiceFactory == null) { this.syncServiceFactory = Factories.SyncServiceFactory; } else { this.syncServiceFactory = syncServiceFactory; } if (!skipInit) { this.RefreshPackages(); } }
public DevicesViewModel(IAdbClient adbClient, IDeviceMonitor deviceMonitor) { _deviceMontior = deviceMonitor; _adbClient = adbClient; UpdateConnectedDevices(); _deviceMontior.DeviceConnected += OnDeviceConnected; _deviceMontior.DeviceDisconnected += OnDeviceDisconnected; }
/// <summary> /// 构造 /// </summary> /// <param name="core"></param> public AdbClientWrapper(IAdbClient core) { this.core = core; if (!core.IsConnected) { core.Connect(); } }
/// <summary> /// Connect to a device via TCP/IP. /// </summary> /// <param name="client"> /// An instance of a class that implements the <see cref="IAdbClient"/> interface. /// </param> /// <param name="address"> /// The IP address of the remote device. /// </param> public static void Connect(this IAdbClient client, IPAddress address) { if (address == null) { throw new ArgumentNullException(nameof(address)); } client.Connect(new IPEndPoint(address, AdbClient.DefaultPort)); }
/// <summary> /// Connect to a device via TCP/IP. /// </summary> /// <param name="client"> /// An instance of a class that implements the <see cref="IAdbClient"/> interface. /// </param> /// <param name="host"> /// The host address of the remote device. /// </param> public static void Connect(this IAdbClient client, string host) { if (string.IsNullOrEmpty(host)) { throw new ArgumentNullException(nameof(host)); } client.Connect(new DnsEndPoint(host, AdbClient.DefaultPort)); }
/// <summary> /// Connect to a device via TCP/IP. /// </summary> /// <param name="client"> /// An instance of a class that implements the <see cref="IAdbClient"/> interface. /// </param> /// <param name="endpoint"> /// The IP endpoint at which the <c>adb</c> server on the device is running. /// </param> public static void Connect(this IAdbClient client, IPEndPoint endpoint) { if (endpoint == null) { throw new ArgumentNullException(nameof(endpoint)); } client.Connect(new DnsEndPoint(endpoint.Address.ToString(), endpoint.Port)); }
// Installation service will provide an adb client public static void Provide(IAdbClient adbClient) { if (adbClient == null) { AdbClient = new AdbClient(); } else { AdbClient = adbClient; } }
public AdbService( IFileSystem fileSystem, IAdbServer adbServer, IAdbClient adbClient, ISyncServiceFactory syncServiceFactory, IEnvironmentService environmentService) { _fileSystem = fileSystem; _adbServer = adbServer; _adbClient = adbClient; _syncServiceFactory = syncServiceFactory; _environmentService = environmentService; }
/// <summary> /// Initializes a new instance of the <see cref="AdbServer"/> class. /// </summary> public AdbServer(IAdbClient adbClient, Func <string, IAdbCommandLineClient> adbCommandLineClientFactory) { if (adbClient == null) { throw new ArgumentNullException(nameof(AdbClient)); } if (adbCommandLineClientFactory == null) { throw new ArgumentNullException(nameof(adbCommandLineClientFactory)); } this.adbCommandLineClientFactory = adbCommandLineClientFactory; this.adbClient = adbClient; }
public static string ExecuteRemoteCommandSync(this IAdbClient client, DeviceData dev, string command) { var finished = false; var retv = ""; var recv = new CommandRecv(); recv.Finished = (result) => { finished = true; retv = result; }; client.ExecuteRemoteCommand(command, dev, recv); while (!finished) { Thread.Sleep(32); } return(retv); }
/// <summary> /// Executes a shell command on the remote device /// </summary> /// <param name="client"> /// An instance of a class that implements the <see cref="IAdbClient"/> interface. /// </param> /// <param name="command">The command to execute</param> /// <param name="device">The device to execute on</param> /// <param name="rcvr">The shell output receiver</param> /// <param name="encoding">The encoding to use.</param> public static void ExecuteRemoteCommand(this IAdbClient client, string command, DeviceData device, IShellOutputReceiver rcvr, Encoding encoding) { try { client.ExecuteRemoteCommandAsync(command, device, rcvr, CancellationToken.None, int.MaxValue).Wait(); } catch (AggregateException ex) { if (ex.InnerExceptions.Count == 1) { throw ex.InnerException; } else { throw; } } }
/// <summary> /// Creates a reversed port forwarding between a local and a remote port. /// </summary> /// <param name="client"> /// An instance of a class that implements the <see cref="IAdbClient"/> interface. /// </param> /// <param name="device"> /// The device to which to forward the connections. /// </param> /// <param name="localPort"> /// The local device port to forward. /// </param> /// <param name="remotePort"> /// The remote host port to forward to /// </param> /// <exception cref="AdbException"> /// failed to submit the reverse command. /// or /// Device rejected command: + resp.Message /// </exception> public static bool CreateReverse(this IAdbClient client, DeviceData device, int localPort, int remotePort) { return(client.CreateReverse(device, $"tcp:{localPort}", $"tcp:{remotePort}", true)); }
/// <summary> /// Executes a shell command on the remote device /// </summary> /// <param name="client"> /// An instance of a class that implements the <see cref="IAdbClient"/> interface. /// </param> /// <param name="command">The command to execute</param> /// <param name="device">The device to execute on</param> /// <param name="rcvr">The shell output receiver</param> public static void ExecuteRemoteCommand(this IAdbClient client, string command, DeviceData device, IShellOutputReceiver rcvr) { ExecuteRemoteCommand(client, command, device, rcvr, AdbClient.Encoding); }
/// <summary> /// Requests the version information from the device. /// </summary> /// <param name="device"> /// The device on which to uninstall the package. /// </param> /// <param name="packageName"> /// The name of the package from which to get the application version. /// </param> public static VersionInfo GetPackageVersion(this IAdbClient client, DeviceData device, string packageName) { PackageManager manager = new PackageManager(client, device); return(manager.GetVersionInfo(packageName)); }
/// <summary> /// Forwards a remote Unix socket to a local TCP socket. /// </summary> /// <param name="client"> /// An instance of a class that implements the <see cref="IAdbClient"/> interface. /// </param> /// <param name="device"> /// The device to which to forward the connections. /// </param> /// <param name="localPort"> /// The local port to forward. /// </param> /// <param name="remoteSocket"> /// The remote Unix socket. /// </param> /// <exception cref="AdbException"> /// The client failed to submit the forward command. /// </exception> /// <exception cref="AdbException"> /// The device rejected command. The error message will include the error message provided by the device. /// </exception> public static int CreateForward(this IAdbClient client, DeviceData device, int localPort, string remoteSocket) { return(client.CreateForward(device, $"tcp:{localPort}", $"local:{remoteSocket}", true)); }
/// <summary> /// Creates a port forwarding between a local and a remote port. /// </summary> /// <param name="client"> /// An instance of a class that implements the <see cref="IAdbClient"/> interface. /// </param> /// <param name="device"> /// The device to which to forward the connections. /// </param> /// <param name="localPort"> /// The local port to forward. /// </param> /// <param name="remotePort"> /// The remote port to forward to /// </param> /// <exception cref="AdbException"> /// failed to submit the forward command. /// or /// Device rejected command: + resp.Message /// </exception> public static void CreateForward(this IAdbClient client, DeviceData device, int localPort, int remotePort) { client.CreateForward(device, $"tcp:{localPort}", $"tcp:{remotePort}", true); }
/// <summary> /// Executes a shell command on the remote device /// </summary> /// <param name="client"> /// An instance of a class that implements the <see cref="IAdbClient"/> interface. /// </param> /// <param name="command">The command to execute</param> /// <param name="device">The device to execute on</param> /// <param name="rcvr">The shell output receiver</param> public static void ExecuteRemoteCommand(this IAdbClient client, string command, DeviceData device, IShellOutputReceiver rcvr) { client.ExecuteRemoteCommand(command, device, rcvr, CancellationToken.None, int.MaxValue).Wait(); }
/// <summary> /// Reboots the specified adb socket address. /// </summary> /// <param name="client"> /// An instance of a class that implements the <see cref="IAdbClient"/> interface. /// </param> /// <param name="device">The device.</param> public static void Reboot(this IAdbClient client, DeviceData device) { client.Reboot(string.Empty, device); }
/// <summary> /// Initializes a new instance of the <see cref="SyncService"/> class. /// </summary> /// <param name="client"> /// A connection to an adb server. /// </param> /// <param name="device"> /// The device on which to interact with the files. /// </param> public SyncService(IAdbClient client, DeviceData device) : this(Factories.AdbSocketFactory(client.EndPoint), device) { }
/// <summary> /// Uninstalls a package from the device. /// </summary> /// <param name="client"> /// The connection to the adb server. /// </param> /// <param name="device"> /// The device on which to uninstall the package. /// </param> /// <param name="packageName"> /// The name of the package to uninstall. /// </param> public static void UninstallPackage(this IAdbClient client, DeviceData device, string packageName) { PackageManager manager = new PackageManager(client, device); manager.UninstallPackage(packageName); }
/// <summary> /// Lists all processes running on the device. /// </summary> /// <param name="device"> /// The device on which to list the processes that are running. /// </param> /// <param name="client"> /// A connection to ADB. /// </param> /// <returns> /// An <see cref="IEnumerable{AndroidProcess}"/> that will iterate over all /// processes that are currently running on the device. /// </returns> public static IEnumerable <AndroidProcess> ListProcesses(this DeviceData device, IAdbClient client) { // There are a couple of gotcha's when listing processes on an Android device. // One way would be to run ps and parse the output. However, the output of // ps differents from Android version to Android version, is not delimited, nor // entirely fixed length, and some of the fields can be empty, so it's almost impossible // to parse correctly. // // The alternative is to directly read the values in /proc/[pid], pretty much like ps // does (see https://android.googlesource.com/platform/system/core/+/master/toolbox/ps.c). // // The easiest way to do the directory listings would be to use the SyncService; unfortunately, // the sync service doesn't work very well with /proc/ so we're back to using ls and taking it // from there. List <AndroidProcess> processes = new List <AndroidProcess>(); // List all processes by doing ls /proc/. // All subfolders which are completely numeric are PIDs // Android 7 and above ships with toybox (https://github.com/landley/toybox), which includes // an updated ls which behaves slightly different. // The -1 parameter is important to make sure each item gets its own line (it's an assumption we // make when parsing output); on Android 7 and above we may see things like: // 1 135 160 171 ioports timer_stats // 10 13533 16056 172 irq tty // 100 136 16066 173 kallsyms uid_cputime // but unfortunately older versions do not handle the -1 parameter well. So we need to branch based // on the API level. We do the branching on the device (inside a shell script) to avoid roundtrips. // This if/then/else syntax was tested on Android 2.x, 4.x and 7 ConsoleOutputReceiver receiver = new ConsoleOutputReceiver(); device.ExecuteShellCommand(client, @"SDK=""$(/system/bin/getprop ro.build.version.sdk)"" if [ $SDK -lt 24 ] then /system/bin/ls /proc/ else /system/bin/ls -1 /proc/ fi".Replace("\r\n", "\n"), receiver); Collection <int> pids = new Collection <int>(); var output = receiver.ToString(); using (StringReader reader = new StringReader(output)) { while (reader.Peek() > 0) { string line = reader.ReadLine(); if (!line.All(c => char.IsDigit(c))) { continue; } var pid = int.Parse(line); pids.Add(pid); } } // For each pid, we can get /proc/[pid]/stat, which contains the process information in a well-defined // format - see http://man7.org/linux/man-pages/man5/proc.5.html. // Doing cat on each file one by one takes too much time. Doing cat on all of them at the same time doesn't work // either, because the command line would be too long. // So we do it 25 processes at at time. StringBuilder catBuilder = new StringBuilder(); ProcessOutputReceiver processOutputReceiver = new ProcessOutputReceiver(); catBuilder.Append("cat "); for (int i = 0; i < pids.Count; i++) { catBuilder.Append($"/proc/{pids[i]}/cmdline /proc/{pids[i]}/stat "); if (i > 0 && (i % 25 == 0 || i == pids.Count - 1)) { device.ExecuteShellCommand(client, catBuilder.ToString(), processOutputReceiver); catBuilder.Clear(); catBuilder.Append("cat "); } } processOutputReceiver.Flush(); return(processOutputReceiver.Processes); }
/// <summary> /// Executes a shell command on the device. /// </summary> /// <param name="device"> /// The device on which to run the command. /// </param> /// <param name="client"> /// The <see cref="IAdbClient"/> to use when executing the command. /// </param> /// <param name="command"> /// The command to execute. /// </param> /// <param name="receiver"> /// Optionally, a <see cref="IShellOutputReceiver"/> that processes the command output. /// </param> /// <param name="cancellationToken">A <see cref="CancellationToken"/> that can be used to cancel the Task.</param> /// <param name="maxTimeToOutputResponse">The max time to output response.</param> public static Task ExecuteShellCommandAsync( this DeviceData device, IAdbClient client, string command, IShellOutputReceiver receiver, CancellationToken cancellationToken, int maxTimeToOutputResponse = int.MaxValue) { return(client.ExecuteRemoteCommandAsync(command, device, receiver, cancellationToken, maxTimeToOutputResponse)); }
/// <summary> /// Executes a shell command on the device. /// </summary> /// <param name="device"> /// The device on which to run the command. /// </param> /// <param name="client"> /// The <see cref="IAdbClient"/> to use when executing the command. /// </param> /// <param name="command"> /// The command to execute. /// </param> /// <param name="receiver"> /// Optionally, a <see cref="IShellOutputReceiver"/> that processes the command output. /// </param> public static void ExecuteShellCommand(this DeviceData device, IAdbClient client, string command, IShellOutputReceiver receiver) { client.ExecuteRemoteCommand(command, device, receiver); }
public AndroidBuildInstaller(Func <string, Task <bool> > userPromptHandler) { _adbClient = InstallationService.AdbClient; _userPromptHandler = userPromptHandler; }