From a12075bb1f3bf834b2e43024d190b55424447d61 Mon Sep 17 00:00:00 2001 From: Jonathan Peppers Date: Tue, 9 Jun 2026 12:13:29 -0500 Subject: [PATCH 1/3] [cleanup] Remove dead code from Mono.AndroidTools and Xamarin.AndroidTools Continues #11607 by deleting public types that have zero callers in the repo and aren't transitively reachable from the live external surface consumed by Xamarin.Android.Build.Debugging.Tasks and Xamarin.Installer.Build.Tasks. Mono.AndroidTools deletions: - Adb/DeviceConnection.cs (DeviceConnection) - Internal/AdbStartServerProcess.cs (IAdbStartServerProcess, AdbStartServerProcess) - Internal/AdbStartWindowsServerProcess.cs (AdbStartWindowsServerProcess) - Util/Win32Interop.cs (Win32Interop, ProcessInfo, SecurityAttributes, StartupInfo, StartF, HandleFlags, CreateProcessFlags, SafeProcessHandle, ProcessWaitHandle) Xamarin.AndroidTools deletions: - Sdks/RegistryEx.cs (entire file - internal class with zero callers) - OS.cs: nested internal RegistryEx class and Wow64 enum (no callers) - AndroidVersion.cs: AndroidVersionExtensions.ToLegacyVersion (no callers) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/Mono.AndroidTools/Adb/DeviceConnection.cs | 506 ------------------ .../Internal/AdbStartServerProcess.cs | 227 -------- .../Internal/AdbStartWindowsServerProcess.cs | 224 -------- src/Mono.AndroidTools/Util/Win32Interop.cs | 241 --------- src/Xamarin.AndroidTools/AndroidVersion.cs | 20 - src/Xamarin.AndroidTools/OS.cs | 120 ----- src/Xamarin.AndroidTools/Sdks/RegistryEx.cs | 135 ----- 7 files changed, 1473 deletions(-) delete mode 100644 src/Mono.AndroidTools/Adb/DeviceConnection.cs delete mode 100644 src/Mono.AndroidTools/Internal/AdbStartServerProcess.cs delete mode 100644 src/Mono.AndroidTools/Internal/AdbStartWindowsServerProcess.cs delete mode 100644 src/Mono.AndroidTools/Util/Win32Interop.cs delete mode 100644 src/Xamarin.AndroidTools/Sdks/RegistryEx.cs diff --git a/src/Mono.AndroidTools/Adb/DeviceConnection.cs b/src/Mono.AndroidTools/Adb/DeviceConnection.cs deleted file mode 100644 index 06a8344768d..00000000000 --- a/src/Mono.AndroidTools/Adb/DeviceConnection.cs +++ /dev/null @@ -1,506 +0,0 @@ -// -// DeviceConnection.cs -// -// Author: -// Michael Hutchinson -// -// Copyright (c) 2014 Xamarin Inc. -// - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Threading; -using Mono.AndroidTools.Util; - -namespace Mono.AndroidTools.Adb -{ - // Connects directly to the adb daemon on a device/emulator and - // forwards streams. - // - // NOTE: The ADB daemon only responds to one connection, though it - // will accept multiple connections. Therefore if the adb server - // is already connected to it, this will not work. - // - // LIMITATIONS: This does not implement any services itself. In - // addition, it doesn't perform any buffering so throughput will - // be bad. - // - // USAGE: - // var c = new TcpClient (); - // c.Connect (IPAddress.Loopback, 5555); - // - // var pc = new DeviceConnection (); - // pc.Connect (c.GetStream ()); - // - // var s = pc.OpenShell (); - // var tw = new StreamWriter (s); - // tw.Write ("ls \n\0"); - // tw.Flush (); - // - // etc. - // - public class DeviceConnection : IDisposable - { - const uint A_SYNC = 0x434e5953; - const uint A_CNXN = 0x4e584e43; - const uint A_AUTH = 0x48545541; - const uint A_OPEN = 0x4e45504f; - const uint A_OKAY = 0x59414b4f; - const uint A_CLSE = 0x45534c43; - const uint A_WRTE = 0x45545257; - - const uint A_VERSION = 0x01000000; - - const int MAX_PAYLOAD = 4096; - const int HEADER_SIZE = 24; - - int targetMaxPayload; - - byte[] writeBuffer = new byte[MAX_PAYLOAD + HEADER_SIZE]; - - Stream stream; - bool disposed; - - string ident; - uint nextLocalID = 1; - Exception readError; - - Dictionary streams = new Dictionary(); - - public void Connect (Stream stream) - { - if (stream == null) - throw new ArgumentNullException ("stream"); - if (disposed) - throw new ObjectDisposedException ("DeviceConnection"); - if (this.stream != null) - throw new InvalidOperationException ("Already connected"); - this.stream = stream; - - string identity = "host::"; - int length = AdbClient.TextEncoding.GetBytes (identity, 0, identity.Length, writeBuffer, HEADER_SIZE); - writeBuffer [length++] = 0; - uint checksum = Checksum (writeBuffer, HEADER_SIZE, length); - - CreateMessage (writeBuffer, A_CNXN, A_VERSION, MAX_PAYLOAD, length, checksum); - - stream.Write (writeBuffer, 0, HEADER_SIZE + length); - - var thread = new Thread (ReadLoop) { IsBackground = true }; - thread.Start (); - } - - public void Dispose () - { - if (disposed) - return; - disposed = true; - - stream.Dispose (); - stream = null; - - foreach (var s in streams) - s.Value.Dispose (); - - streams = null; - } - - void CheckError () - { - if (readError != null) - throw new Exception ("Error reading from device", readError); - if (disposed) - throw new ObjectDisposedException ("DeviceConnection"); - } - - public Stream OpenStream (string serviceName) - { - CheckError (); - - var s = new ServiceStream (this, nextLocalID++); - streams [s.LocalID] = s; - - int length = AdbClient.TextEncoding.GetBytes (serviceName, 0, serviceName.Length, writeBuffer, HEADER_SIZE); - writeBuffer [length++] = 0; - uint checksum = Checksum (writeBuffer, HEADER_SIZE, length); - - Debug.WriteLine ("W OKAY local {0}", s.LocalID); - - CreateMessage (writeBuffer, A_OPEN, s.LocalID, 0, length, checksum); - stream.Write (writeBuffer, 0, HEADER_SIZE + length); - - SetReady (s); - - return s; - } - - public Stream OpenTcp (short port) - { - return OpenStream ("tcp:" + port); - } - - public Stream OpenLocal (string name) - { - return OpenStream ("local:" + name); - } - - public Stream OpenLocalReserved (string name) - { - return OpenStream ("localreserved:" + name); - } - - public Stream OpenLocalAbstract (string name) - { - return OpenStream ("localabstract:" + name); - } - - public Stream OpenLocalFileSystem (string name) - { - return OpenStream ("localfilesystem:" + name); - } - - public Stream OpenDev (string name) - { - return OpenStream ("dev:" + name); - } - - public Stream OpenFrameBuffer () - { - return OpenStream ("framebuffer:"); - } - - public Stream OpenJdwp (int pid) - { - return OpenStream ("jdwp:" + pid); - } - - public Stream OpenShell (string command = null) - { - return OpenStream ("shell:" + command); - } - - public Stream OpenSync () - { - return OpenStream ("sync:"); - } - - public Stream OpenRemount () - { - return OpenStream ("remount:"); - } - - public Stream OpenReboot (string arg = null) - { - return OpenStream ("reboot:" + arg); - } - - public Stream OpenRoot () - { - return OpenStream ("root:"); - } - - public Stream OpenBackup (string arg = null) - { - return OpenStream ("backup:" + arg); - } - - public Stream OpenRestore() - { - return OpenStream ("restore:"); - } - - public Stream OpenTcpip (short port = 0) - { - return OpenStream ("tcpip:" + port); - } - - public Stream OpenUsb () - { - return OpenStream ("usb:"); - } - - public Stream OpenReverse (string cookie) - { - return OpenStream ("reverse:"); - } - - void Close (ServiceStream stream) - { - if (streams.Remove (stream.LocalID)) { - CreateMessage (writeBuffer, A_CLSE, stream.LocalID, stream.RemoteID, 0, 0); - stream.Write (writeBuffer, 0, HEADER_SIZE); - } - } - - void ReadLoop () - { - byte[] readBuffer = new byte[HEADER_SIZE]; - - try { - while (!disposed) { - stream.ReadFull (readBuffer, 0, HEADER_SIZE); - - uint command, arg0, arg1, checksum; - - int length; - ReadMessage (readBuffer, out command, out arg0, out arg1, out length, out checksum); - - byte[] payload = null; - if (length > 0) { - payload = new byte[length]; - stream.ReadFull (payload, 0, length); - if (Checksum (payload, 0, length) != checksum) - throw new Exception ("Checksum failed"); - } - - if (ident == null) { - if (command != A_CNXN) - throw new Exception ("Not yet identified"); - if (arg0 != A_VERSION) - throw new Exception ("Version mismatch, got " + arg0); - targetMaxPayload = (int)arg1; - ident = AdbClient.TextEncoding.GetString (payload); - Debug.WriteLine ("CNXN"); - continue; - } - - switch (command) { - case A_OKAY: - HandleOkay (arg1, arg0); - continue; - case A_WRTE: - HandleWrite (arg1, payload); - continue; - case A_CLSE: - HandleClose (arg1, arg0); - continue; - case A_AUTH: - case A_SYNC: - case A_OPEN: - throw new NotSupportedException (); - case A_CNXN: - throw new Exception ("Already identified"); - default: - throw new Exception ("Unknown command " + command); - } - } - } catch (Exception ex) { - readError = ex; - } - } - - void HandleClose (uint localID, uint remoteID) - { - Debug.WriteLine ("R CLSE local {0} remote {1}", localID, remoteID); - - ServiceStream value; - if (!streams.TryGetValue (localID, out value)) - return; - value.Dispose (); - } - - void HandleOkay (uint localID, uint remoteID) - { - Debug.WriteLine ("R OKAY local {0} remote {1}", localID, remoteID); - - ServiceStream value; - if (!streams.TryGetValue (localID, out value)) - return; - value.WriteEvent.Set (); - value.RemoteID = remoteID; - } - - void HandleWrite (uint localID, byte[] payload) - { - Debug.WriteLine ("R WRTE local {0} payload {1}", localID, payload.Length); - - ServiceStream value; - if (!streams.TryGetValue (localID, out value)) - return; - - if (value.Incoming != null) { - // not ready, invalid - value.Dispose (); - return; - } - - value.Incoming = payload; - value.ReadEvent.Set (); - } - - void SetReady (ServiceStream s) - { - Debug.WriteLine ("W OKAY local {0} payload {1}", s.LocalID, s.RemoteID); - - var buf = new byte[HEADER_SIZE]; - CreateMessage (buf, A_OKAY, s.LocalID, s.RemoteID, 0, 0); - stream.Write (buf, 0, HEADER_SIZE); - } - - static void CreateMessage (byte[] buf, uint command, uint arg0, uint arg1, int length, uint checksum) - { - UIntToBytes (command, buf, 0); - UIntToBytes (arg0, buf, 4); - UIntToBytes (arg1, buf, 8); - UIntToBytes ((uint)length, buf, 12); - UIntToBytes (checksum, buf, 16); - - UIntToBytes (command ^ 0xffffffff, buf, 20); - } - - static void ReadMessage (byte[] buf, out uint command, out uint arg0, out uint arg1, out int length, out uint checksum) - { - command = BytesToUInt (buf, 0); - arg0 = BytesToUInt (buf, 4); - arg1 = BytesToUInt (buf, 8); - length = (int)BytesToUInt (buf, 12); - checksum = BytesToUInt (buf, 16); - - if (BytesToUInt (buf, 20) != (command ^ 0xffffffff)) - throw new Exception ("Corrupt magic number"); - } - - static uint Checksum (byte[] buf, int offset, int length) - { - //the docs lie, it's not a CRC32, it's a byte-by-byte sum - uint checksum = 0; - for (int i = offset; i < length + offset; i++) { - unchecked { - checksum += buf [i]; - } - } - return checksum; - } - - static uint BytesToUInt (byte[] buf, int offset) - { - return - (uint) buf[3+offset] << 24 | - (uint) buf[2+offset] << 16 | - (uint) buf[1+offset] << 8 | - (uint) buf[0+offset]; - } - - static void UIntToBytes (uint val, byte[] buf, int pos) - { - buf[pos+3] = (byte) (val >> 24); - buf[pos+2] = (byte) ((val >> 16) & 0x000000FF); - buf[pos+1] = (byte) ((val >> 08) & 0x000000FF); - buf[pos+0] = (byte) (val & 0x000000FF); - } - - class ServiceStream : Stream - { - public ManualResetEvent WriteEvent = new ManualResetEvent (false); - public ManualResetEvent ReadEvent = new ManualResetEvent (false); - - public byte[] Incoming; - - int incomingRead; - - DeviceConnection connection; - - public uint LocalID { get; private set; } - public uint RemoteID { get; set; } - - public ServiceStream (DeviceConnection connection, uint localID) - { - this.connection = connection; - this.LocalID = localID; - } - - public override int Read (byte[] buffer, int offset, int count) - { - connection.CheckError (); - - ReadEvent.WaitOne (); - - int read = System.Math.Min (count, Incoming.Length - incomingRead); - Array.Copy (Incoming, incomingRead, buffer, offset, read); - - incomingRead += read; - - if (incomingRead == Incoming.Length) { - ReadEvent.Reset (); - Incoming = null; - incomingRead = 0; - connection.SetReady (this); - } - - return read; - } - - public override void Write (byte[] buffer, int offset, int count) - { - connection.CheckError (); - - var msg = new byte[HEADER_SIZE + connection.targetMaxPayload]; - - int remaining = count; - while (remaining > 0) { - var write = System.Math.Min (connection.targetMaxPayload, remaining); - uint checksum = Checksum (buffer, offset, write); - Array.Copy (buffer, offset, msg, HEADER_SIZE, write); - CreateMessage (msg, A_WRTE, 0, RemoteID, write, checksum); - - offset += write; - remaining -= write; - - WriteEvent.WaitOne (); - connection.stream.Write (msg, 0, HEADER_SIZE + write); - } - } - - protected override void Dispose (bool disposing) - { - if (disposing) { - connection.Close (this); - } - base.Dispose (disposing); - } - - public override void Flush () - { - } - - public override long Seek (long offset, SeekOrigin origin) - { - throw new NotSupportedException (); - } - - public override void SetLength (long value) - { - throw new NotSupportedException (); - } - - public override bool CanRead { - get { return true; } - } - - public override bool CanSeek { - get { return false; } - } - - public override bool CanWrite { - get { return true; } - } - - public override long Length { - get { - throw new NotSupportedException (); - } - } - - public override long Position { - get { - throw new NotSupportedException (); - } - set { - throw new NotSupportedException (); - } - } - } - } -} diff --git a/src/Mono.AndroidTools/Internal/AdbStartServerProcess.cs b/src/Mono.AndroidTools/Internal/AdbStartServerProcess.cs deleted file mode 100644 index e1257e477c8..00000000000 --- a/src/Mono.AndroidTools/Internal/AdbStartServerProcess.cs +++ /dev/null @@ -1,227 +0,0 @@ -// -// AdbStartServerProcess.cs -// -// Author: -// Michael Hutchinson -// -// Copyright (c) 2011 Xamarin Inc. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -using System; -using System.Threading; -using System.IO; -using Mono.AndroidTools.Util; - -namespace Mono.AndroidTools.Internal -{ - interface IAdbStartServerProcess : IDisposable - { - bool Success { get; } - bool Completed { get; } - event EventHandler Exited; - string GetOutput (); - void Cancel (); - } - - //HACK: using Process and a thread instead of MD process APIs because of weird stuff adb start-server does - // When using adb start-server, .NET's StandardOutput.Read blocks or even throws a "stdout not redirected" - // after all data is read and the process has ended - // This seems to be because adb forks, and even though the original process exits, the output stream somehow - // stays alive. It's probably been passed over to the new process somehow. - // - class AdbStartServerProcess : IAdbStartServerProcess - { - //ManualResetEvent endEventErr = new ManualResetEvent (false); - Thread captureOutputThread; //, captureErrorThread; - System.Diagnostics.Process proc; - object lockObj = new object (); - EventHandler exited; - StringWriter output = new StringWriter (); - bool success = false, completed = false; - - public bool Success { get { return success; } } - public bool Completed { get { return completed; } } - - public string GetOutput () - { - return output.ToString (); - } - - public AdbStartServerProcess (string adbExe, EventHandler exited) - { - this.exited = exited; - - proc = new System.Diagnostics.Process (); - proc.StartInfo = new System.Diagnostics.ProcessStartInfo (adbExe, "start-server") { - UseShellExecute = false, - RedirectStandardOutput = true, - RedirectStandardError = true, - CreateNoWindow = true, - }; - proc.Start (); - - captureOutputThread = new Thread (CaptureOutput) { - Name = "Adb output reader", - IsBackground = true, - }; - captureOutputThread.Start (); - - /* - captureErrorThread = new Thread (CaptureError) { - Name = "Adb error reader", - IsBackground = true, - }; - captureErrorThread.Start ();*/ - } - - public event EventHandler Exited { - add { exited += value; } - remove { exited -= value; } - } - - void CaptureOutput () - { - bool hadException = false; - try { - //HACK: this is just long enough to contain the expected adb output string when successfully starting the server - //if we try to read too much, we will stop responding somewhere in native code on Windows - char[] buffer = new char [86]; - int nr; - while ((nr = proc.StandardOutput.Read (buffer, 0, buffer.Length)) > 0) { - var s = new string (buffer, 0, nr); - output.Write (s); - if (s.Contains ("daemon started successfully")) { - success = true; - /* - lock (lockObj) { - captureErrorThread.Abort (); - captureErrorThread = null; - }*/ - output.Dispose (); - proc.StandardOutput.Close (); - proc.StandardError.Close (); - break; - } - } - } catch (ThreadAbortException) { - hadException = true; - Thread.ResetAbort (); - } catch (Exception ex) { - hadException = true; - AndroidLogger.LogError ("Unhandled exception in adb output reader", ex); - } finally { - //proc can be null if this class is disposed before the output reader finishes - var p = proc; - - /* - if (endEventErr != null) - WaitHandle.WaitAll (new WaitHandle[] {endEventErr} ); - */ - - //HACK: if success is true at this point, then we have determined that adb is forking a new server - // and bailed out early to avoid the Windows native hang that happens when we read too far in the adb - // stdout stream that gets passed over to the new process. - // See: - // - // Unfortunately, if the fork happens then the error stream thread hangs in the same way, and cannot - // even be aborted. We avoid this by *only* reading stderr if this condition is false. Instead we - // only read stderr after the output thread is done. Sadly this means we lose stderr/stdout - // interleaving, and the adb process could deadlock if stderr fills up too much. - if (!success && p != null) { - string line; - while ((line = p.StandardError.ReadLine ()) != null) - output.WriteLine (line); - } - - if (!success && p != null) { - // if we did not have an exception, wait for the proc to exit completel before checking for final success status - // we are sometimes getting to this point and checking for exit status but because the process has not exited, we incorectly set success false - // when in fact it did succeed. this causes XS to stop polling for device updates - if (!hadException) - p.WaitForExit (5000); - - if (p.HasExited && p.ExitCode <= 0) - success = true; - } - - completed = true; - captureOutputThread = null; - exited (this, EventArgs.Empty); - } - } - /* - void CaptureError () - { - try { - char[] buffer = new char [1024]; - int nr; - while ((nr = proc.StandardError.Read (buffer, 0, buffer.Length)) > 0) { - var s = new string (buffer, 0, nr); - output.Write (s); - } - } catch (ThreadAbortException) { - Thread.ResetAbort (); - } catch (Exception ex) { - LoggingService.LogError ("Unhandled exception in adb error reader", ex); - } finally { - lock (lockObj) { - if (endEventErr != null) - endEventErr.Set (); - } - } - }*/ - - public void Dispose () - { - var proc = this.proc; - lock (lockObj) { - if (this.proc == null) - return; - this.proc = null; - } - if (captureOutputThread != null) { - if (captureOutputThread.IsAlive) { - try { - captureOutputThread.Abort (); - } catch {} - } - captureOutputThread = null; - } - /* - if (captureErrorThread != null) { - if (captureErrorThread.IsAlive) { - try { - captureErrorThread.Abort (); - } catch {} - } - captureErrorThread = null; - }*/ - proc.Dispose (); - } - - public void Cancel () - { - var proc = this.proc; - if (proc.HasExited) - return; - proc.Kill (); - } - } -} diff --git a/src/Mono.AndroidTools/Internal/AdbStartWindowsServerProcess.cs b/src/Mono.AndroidTools/Internal/AdbStartWindowsServerProcess.cs deleted file mode 100644 index cf29d7bbd04..00000000000 --- a/src/Mono.AndroidTools/Internal/AdbStartWindowsServerProcess.cs +++ /dev/null @@ -1,224 +0,0 @@ -// -// AdbStartWindowsServerProcess.cs -// -// Author: -// Michael Hutchinson -// -// Copyright (c) 2011 Xamarin Inc. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -using System; -using System.Threading; -using System.IO; -using System.Runtime.InteropServices; -using Mono.AndroidTools.Util; - -namespace Mono.AndroidTools.Internal -{ - // adb start-server has issues on Windows. When it starts the server, it forks a process, which - // stays alive indefinitely. This new process carries off all the handles from the adb - // commandline process and hence keeps them alive as long as it lives. The hardcoded behaviour - // of .NET is to pass all handles to child processes. That means that the adb commandline - // process and hence the server process gets all MonoDevelop's handles and keeps them alive - // indefinitely. However, the new process is on a new process tree from the one MD started, - // so we can't (easily) kill it when MD exits (nor do we necessarily want to do so). - // - // And if we do redirect adb's stdout and stderr, blocking reads on them get stuck in native code - // and cannot be interrupted even when the process exits, because the child (server) process keeps - // them open and doesn't write to them frequently. - // - // We have two workarounds for this, and both involve using P/Invoke to call CreateProcess directly. - // a) Start the process with bInheritHandles set to false. That means we can't redirect - // stdout/stderr, can only report the exit code. - // b) Redirect the process's stdout and stderr to a file that we can read when reporting errors. - // Mark this MD's stdout/stderr/stdin as noninheritable, so the child cannot hold them - // open. This is hacky, as other child processes may have a legitimate reason to use these - // handles. There could also be problems if MD has other inheritable handles. - // - // For now, (a) is the default behavior, and (b) can be enabled by defining ADB_SERVER_OUTPUT. - // - // Possibly a better (but more complex solution) would be to implement a wrapper process for - // adb start-server that redirects stdout/stderr to a log file, and start that process without - // inheriting handles. - // - // More info: - // http://www.davidmoore.info/2011/06/21/when-system-diagnostics-process-creates-a-process-it-inherits-inheritable-handles-from-the-parent-process/ - // http://social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/94ba760c-7080-4614-8a56-15582c48f900/ - // - class AdbStartWindowsServerProcess : IAdbStartServerProcess - { - Win32Interop.ProcessWaitHandle waitHandle; - Win32Interop.SafeProcessHandle hProcess; - EventHandler exited; - bool completed; - int exitCode; - -#if ADB_SERVER_OUTPUT - string logFile; - - public AdbStartWindowsServerProcess (string adbExe, string logFile, EventHandler exited) - { - this.logFile = logFile; -#endif - - public AdbStartWindowsServerProcess (string adbExe, EventHandler exited) - { - if (exited != null) - this.Exited += exited; - - //the commandline arg has to include argv[0] - var pb = new ProcessArgumentBuilder (); - pb.AddQuoted (adbExe); - pb.Add ("start-server"); - var commandline = pb.ToString (); - - var startupInfo = new Win32Interop.StartupInfo (); - startupInfo.cb = (uint) Marshal.SizeOf (startupInfo); - - Win32Interop.ProcessInfo processInformation; -#if ADB_SERVER_OUTPUT - //HACK: prevent the new process from inheriting our stdhandles - Win32Interop.SetHandleInformation (Win32Interop.StdInputHandle, Win32Interop.HandleFlags.Inherit, Win32Interop.HandleFlags.None); - Win32Interop.SetHandleInformation (Win32Interop.StdOutputHandle, Win32Interop.HandleFlags.Inherit, Win32Interop.HandleFlags.None); - Win32Interop.SetHandleInformation (Win32Interop.StdErrorHandle, Win32Interop.HandleFlags.Inherit, Win32Interop.HandleFlags.None); - - var logStream = File.Open (logFile, FileMode.Create, FileAccess.Write, FileShare.Inheritable | FileShare.Read); - - startupInfo.dwFlags = Win32Interop.StartF.UseStdHandles; - startupInfo.hStdOutput = logStream.SafeFileHandle.DangerousGetHandle (); - startupInfo.hStdError = startupInfo.hStdOutput; - startupInfo.hStdInput = IntPtr.Zero; - - bool success; - success = Win32Interop.CreateProcess (null, commandline, IntPtr.Zero, IntPtr.Zero, true, - Win32Interop.CreateProcessFlags.CreateNoWindow, IntPtr.Zero, null, ref startupInfo, out processInformation); - logStream.Close (); -#else - bool success; - success = Win32Interop.CreateProcess (null, commandline, IntPtr.Zero, IntPtr.Zero, false, - Win32Interop.CreateProcessFlags.CreateNoWindow, IntPtr.Zero, null, ref startupInfo, out processInformation); -#endif - - if (!success) - Win32Interop.ThrowWin32Error (); - - hProcess = new Win32Interop.SafeProcessHandle (processInformation.hProcess, true); - var hThread = new Win32Interop.SafeProcessHandle (processInformation.hThread, true); - hThread.Close (); - - waitHandle = new Win32Interop.ProcessWaitHandle (hProcess); - ThreadPool.RegisterWaitForSingleObject (waitHandle, ProcessExited, null, 10 * 1000, true); - } - - void ProcessExited (object state, bool timedOut) - { - try { - if (timedOut) { - AndroidLogger.LogError ("Timeout checking adb start-server status"); - //TODO: kill process - exitCode = int.MaxValue; - } else { - if (!Win32Interop.GetExitCodeProcess (hProcess.DangerousGetHandle (), out exitCode)) { - int err = Marshal.GetLastWin32Error (); - AndroidLogger.LogError ( - string.Format ("Error checking adb start-server status: win32 code {0}", err)); - exitCode = int.MaxValue; - } - } - EventHandler evt; - lock (this) { - completed = true; - evt = this.exited; - } - if (evt != null) - evt (this, EventArgs.Empty); - } catch (Exception ex) { - AndroidLogger.LogError ("Error checking adb start-server status", ex); - } - Dispose (); - } - - public event EventHandler Exited { - add { - bool invoke = false; - lock (this) { - if (completed) - invoke = true; - exited += value; - } - if (invoke) - value (this, EventArgs.Empty); - } - remove { - lock (this) { - exited -= value; - } - } - } - - public bool Success { - get { - return exitCode == 0; - } - } - - public bool Completed { - get { - return completed; - } - } - - public string GetOutput () - { -#if ADB_SERVER_OUTPUT - return File.ReadAllText (logFile); -#else - return string.Format ("Error code {0}", exitCode); -#endif - } - - public void Dispose () - { - var hp = hProcess; - if (hp != null) { - hp.Dispose (); - hProcess = null; - } - var wh = waitHandle; - if (wh != null) { - wh.Dispose (); - wh = null; - } - } - - public void Cancel () - { - if (completed) - return; - var hp = hProcess; - if (hp == null) - return; - if (!Win32Interop.TerminateProcess (hp.DangerousGetHandle (), UInt32.MaxValue)) { - int err = Marshal.GetLastWin32Error (); - throw new System.ComponentModel.Win32Exception (err); - } - } - } -} \ No newline at end of file diff --git a/src/Mono.AndroidTools/Util/Win32Interop.cs b/src/Mono.AndroidTools/Util/Win32Interop.cs deleted file mode 100644 index ca5528423fe..00000000000 --- a/src/Mono.AndroidTools/Util/Win32Interop.cs +++ /dev/null @@ -1,241 +0,0 @@ -// -// Win32Interop.cs -// -// Author: -// Michael Hutchinson -// -// Copyright (c) 2011 Xamarin Inc. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -using System; -using System.Runtime.InteropServices; -using System.Threading; - -namespace Mono.AndroidTools.Util -{ - //Signatures from pinvoke.net with modifications and additions - static class Win32Interop - { - [DllImport ("kernel32.dll", CharSet=CharSet.Unicode, SetLastError=true, EntryPoint="CreateProcessW")] - public static extern bool CreateProcess ( - string lpApplicationName, - string lpCommandLine, - ref SecurityAttributes lpProcessAttributes, - ref SecurityAttributes lpThreadAttributes, - bool bInheritHandles, - CreateProcessFlags dwCreationFlags, - IntPtr lpEnvironment, - string lpCurrentDirectory, - [In] ref StartupInfo lpStartupInfo, - out ProcessInfo lpProcessInformation); - - [DllImport ("kernel32.dll", CharSet=CharSet.Unicode, SetLastError=true, EntryPoint="CreateProcessW")] - public static extern bool CreateProcess ( - string lpApplicationName, - string lpCommandLine, - IntPtr lpProcessAttributes, - IntPtr lpThreadAttributes, - bool bInheritHandles, - CreateProcessFlags dwCreationFlags, - IntPtr lpEnvironment, - string lpCurrentDirectory, - [In] ref StartupInfo lpStartupInfo, - out ProcessInfo lpProcessInformation); - - [DllImport ("kernel32.dll", CharSet=CharSet.Unicode, SetLastError=true, EntryPoint="TerminateProcess")] - public static extern bool TerminateProcess (IntPtr hProcess, uint exitCode); - - [StructLayout (LayoutKind.Sequential)] - public struct ProcessInfo - { - public IntPtr hProcess; - public IntPtr hThread; - public Int32 ProcessId; - public Int32 ThreadId; - } - - [StructLayout (LayoutKind.Sequential)] - public struct SecurityAttributes - { - public int length; - public IntPtr lpSecurityDescriptor; - public bool bInheritHandle; - } - - [StructLayout (LayoutKind.Sequential, CharSet=CharSet.Unicode)] - public struct StartupInfo - { - public uint cb; - public string lpReserved; - public string lpDesktop; - public string lpTitle; - public uint dwX; - public uint dwY; - public uint dwXSize; - public uint dwYSize; - public uint dwXCountChars; - public uint dwYCountChars; - public uint dwFillAttribute; - public StartF dwFlags; - public short wShowWindow; -#pragma warning disable 0169 - short cbReserved2; - IntPtr lpReserved2; -#pragma warning restore 0169 - public IntPtr hStdInput; - public IntPtr hStdOutput; - public IntPtr hStdError; - } - - [Flags] - public enum StartF : uint - { - None = 0, - ForceOnFeedback = 0x00000040, - ForceOffFeedback = 0x00000080, - PreventPinning = 0x00002000, - RunFullscreen = 0x00000020, - TitleIsAppID = 0x00001000, - TitleIsLinkName = 0x00000800, - UseCountChars = 0x00000008, - UseFillAttribute = 0x00000010, - UseHotKey = 0x00000200, - UsePosition = 0x00000004, - UseShowWindow = 0x00000001, - UseSize = 0x00000002, - UseStdHandles = 0x00000100, - } - - [DllImport ("kernel32.dll", SetLastError=true)] - public static extern Int32 WaitForSingleObject (IntPtr Handle, Int32 Wait); - - [DllImport ("kernel32.dll", SetLastError=true)] - public static extern bool GetExitCodeProcess (IntPtr Handle, out int lpExitCode); - - [DllImport ("kernel32.dll", SetLastError=true)] - public static extern bool SetHandleInformation (IntPtr hObject, HandleFlags dwMask, HandleFlags dwFlags); - - [Flags] - public enum HandleFlags - { - None = 0, - Inherit = 1, - ProtectFromClose = 2 - } - - public static void ThrowWin32Error () - { - throw new Exception (string.Format ("Win32 error: {0}", Marshal.GetLastWin32Error ())); - } - - [DllImport ("kernel32.dll", SetLastError = true)] - public static extern IntPtr GetStdHandle (int nStdHandle); - - const int STD_INPUT_HANDLE = -10; - const int STD_OUTPUT_HANDLE = -11; - const int STD_ERROR_HANDLE = -12; - - public static IntPtr StdInputHandle { - get { - IntPtr handle = GetStdHandle (STD_INPUT_HANDLE); - if (handle == IntPtr.Zero) - ThrowWin32Error (); - return handle; - } - } - - public static IntPtr StdOutputHandle { - get { - IntPtr handle = GetStdHandle (STD_OUTPUT_HANDLE); - if (handle == IntPtr.Zero) - ThrowWin32Error (); - return handle; - } - } - - public static IntPtr StdErrorHandle { - get { - IntPtr handle = GetStdHandle (STD_ERROR_HANDLE); - if (handle == IntPtr.Zero) - ThrowWin32Error (); - return handle; - } - } - - [Flags] - public enum CreateProcessFlags : uint - { - None = 0, - CreateBreakawayFromJob = 0x01000000, - CreateDefaultErrorMode = 0x04000000, - CreateNewConsole = 0x00000010, - CreateNewProcessGroup = 0x00000200, - CreateNoWindow = 0x08000000, - CreateProtectedProcess = 0x00040000, - CreatePreserveCodeAuthzLevel = 0x02000000, - CreateSeparateWowVdm = 0x00000800, - CreateSharedWowVvm = 0x00001000, - CreateSuspended = 0x00000004, - CreateUnicodeEnvironment = 0x00000400, - DebugOnlyThisProcess = 0x00000002, - DebugProcess = 0x00000001, - DetachedProcess = 0x00000008, - ExtendedStartupInfoPresent = 0x00080000, - InheritParentAffinity = 0x00010000, - - AboveNormalPriorityClass = 0x00008000, - BelowNormalPriorityClass = 0x00004000, - HighPriorityClass = 0x00000080, - IdlePriorityClass = 0x00000040, - NormalPriorityClass = 0x00000020, - RealtimePriorityClass = 0x00000100, - } - - public class SafeProcessHandle : Microsoft.Win32.SafeHandles.SafeHandleZeroOrMinusOneIsInvalid - { - public SafeProcessHandle (IntPtr handle, bool ownsHandle) : base (ownsHandle) - { - base.handle = handle; - } - - protected override bool ReleaseHandle () - { - return CloseHandle (handle); - } - - [DllImport("kernel32.dll", SetLastError=true)] - [return: MarshalAs (UnmanagedType.Bool)] - static extern bool CloseHandle (IntPtr hObject); - - static void ThrowWin32Error () - { - throw new Exception (string.Format ("Win32 error: {0}", Marshal.GetLastWin32Error ())); - } - } - - public class ProcessWaitHandle : WaitHandle - { - public ProcessWaitHandle (SafeProcessHandle processHandle) - { - SafeWaitHandle = new Microsoft.Win32.SafeHandles.SafeWaitHandle (processHandle.DangerousGetHandle (), false); - } - } - } -} \ No newline at end of file diff --git a/src/Xamarin.AndroidTools/AndroidVersion.cs b/src/Xamarin.AndroidTools/AndroidVersion.cs index 65ea00de8d8..36f1f7dcc97 100644 --- a/src/Xamarin.AndroidTools/AndroidVersion.cs +++ b/src/Xamarin.AndroidTools/AndroidVersion.cs @@ -180,24 +180,4 @@ public override int GetHashCode () }; } - public static class AndroidVersionExtensions - { -#pragma warning disable CS0618 // Type or member is obsolete - - public static AndroidVersion ToLegacyVersion (this Xamarin.Android.Tools.AndroidVersion androidVersion) - { - if (!Version.TryParse (androidVersion.OSVersion, out Version version)) - return null; - - return new AndroidVersion ( - androidVersion.ApiLevel, - androidVersion.OSVersion, - androidVersion.CodeName, - version - ); - } - -#pragma warning restore CS0618 - - } } diff --git a/src/Xamarin.AndroidTools/OS.cs b/src/Xamarin.AndroidTools/OS.cs index d275e2842be..59cb86c2e48 100644 --- a/src/Xamarin.AndroidTools/OS.cs +++ b/src/Xamarin.AndroidTools/OS.cs @@ -129,124 +129,4 @@ public static string GetShortPathName (string path) return sb.ToString (); } } - - internal static class RegistryEx - { - const string ADVAPI = "advapi32.dll"; - - public static UIntPtr CurrentUser = (UIntPtr)0x80000001; - public static UIntPtr LocalMachine = (UIntPtr)0x80000002; - - [DllImport (ADVAPI, CharSet = CharSet.Unicode, SetLastError = true)] - static extern int RegOpenKeyEx (UIntPtr hKey, string subKey, uint reserved, uint sam, out UIntPtr phkResult); - - [DllImport (ADVAPI, CharSet = CharSet.Unicode, SetLastError = true)] - static extern int RegQueryValueExW (UIntPtr hKey, string lpValueName, int lpReserved, out uint lpType, - StringBuilder lpData, ref uint lpcbData); - - [DllImport (ADVAPI, CharSet = CharSet.Unicode, SetLastError = true)] - static extern int RegSetValueExW (UIntPtr hKey, string lpValueName, int lpReserved, - uint dwType, string data, uint cbData); - - [DllImport (ADVAPI, CharSet = CharSet.Unicode, SetLastError = true)] - static extern int RegSetValueExW (UIntPtr hKey, string lpValueName, int lpReserved, - uint dwType, IntPtr data, uint cbData); - - [DllImport (ADVAPI, CharSet = CharSet.Unicode, SetLastError = true)] - static extern int RegCreateKeyEx (UIntPtr hKey, string subKey, uint reserved, string @class, uint options, - uint samDesired, IntPtr lpSecurityAttributes, out UIntPtr phkResult, out Disposition lpdwDisposition); - - [DllImport ("advapi32.dll", SetLastError = true)] - static extern int RegCloseKey (UIntPtr hKey); - - public static string GetValueString (UIntPtr key, string subkey, string valueName, Wow64 wow64) - { - UIntPtr regKeyHandle; - uint sam = (uint)Rights.QueryValue + (uint)wow64; - if (RegOpenKeyEx (key, subkey, 0, sam, out regKeyHandle) != 0) - return null; - - try { - uint type; - var sb = new StringBuilder (2048); - uint cbData = (uint) sb.Capacity; - if (RegQueryValueExW (regKeyHandle, valueName, 0, out type, sb, ref cbData) == 0) { - return sb.ToString (); - } - return null; - } finally { - RegCloseKey (regKeyHandle); - } - } - - public static void SetValueString (UIntPtr key, string subkey, string valueName, string value, Wow64 wow64) - { - UIntPtr regKeyHandle; - uint sam = (uint)(Rights.CreateSubKey | Rights.SetValue) + (uint)wow64; - uint options = (uint) Options.NonVolatile; - Disposition disposition; - if (RegCreateKeyEx (key, subkey, 0, null, options, sam, IntPtr.Zero, out regKeyHandle, out disposition) != 0) { - throw new Exception ("Could not open or create key"); - } - - try { - uint type = (uint)ValueType.String; - uint lenBytesPlusNull = ((uint)value.Length + 1) * 2; - var result = RegSetValueExW (regKeyHandle, valueName, 0, type, value, lenBytesPlusNull); - if (result != 0) - throw new Exception (string.Format ("Error {0} setting registry '{1}{2}' with value '{3}'='{4}'", - result, key, subkey, valueName, value)); - } finally { - RegCloseKey (regKeyHandle); - } - } - - [Flags] - enum Rights : uint - { - None = 0, - QueryValue = 0x0001, - SetValue = 0x0002, - CreateSubKey = 0x0004, - EnumerateSubKey = 0x0008, - } - - enum Options - { - BackupRestore = 0x00000004, - CreateLink = 0x00000002, - NonVolatile = 0x00000000, - Volatile = 0x00000001, - } - - public enum Wow64 : uint - { - Key64 = 0x0100, - Key32 = 0x0200, - } - - enum ValueType : uint - { - None = 0, //REG_NONE - String = 1, //REG_SZ - UnexpandedString = 2, //REG_EXPAND_SZ - Binary = 3, //REG_BINARY - DWord = 4, //REG_DWORD - DWordLittleEndian = 4, //REG_DWORD_LITTLE_ENDIAN - DWordBigEndian = 5, //REG_DWORD_BIG_ENDIAN - Link = 6, //REG_LINK - MultiString = 7, //REG_MULTI_SZ - ResourceList = 8, //REG_RESOURCE_LIST - FullResourceDescriptor = 9, //REG_FULL_RESOURCE_DESCRIPTOR - ResourceRequirementsList = 10, //REG_RESOURCE_REQUIREMENTS_LIST - QWord = 11, //REG_QWORD - QWordLittleEndian = 11, //REG_QWORD_LITTLE_ENDIAN - } - - enum Disposition : uint - { - CreatedNewKey = 0x00000001, - OpenedExistingKey = 0x00000002, - } - } } diff --git a/src/Xamarin.AndroidTools/Sdks/RegistryEx.cs b/src/Xamarin.AndroidTools/Sdks/RegistryEx.cs deleted file mode 100644 index cb9f9c425cc..00000000000 --- a/src/Xamarin.AndroidTools/Sdks/RegistryEx.cs +++ /dev/null @@ -1,135 +0,0 @@ -// -// RegistryEx.cs -// -// Authors: -// Michael Hutchinson -// -// Copyright 2012 Xamarin Inc. All rights reserved. -// - -using System; -using System.Runtime.InteropServices; -using System.Text; - -namespace Xamarin.AndroidTools.Sdks -{ - internal static class RegistryEx - { - const string ADVAPI = "advapi32.dll"; - - public static UIntPtr CurrentUser = (UIntPtr)0x80000001; - public static UIntPtr LocalMachine = (UIntPtr)0x80000002; - - [DllImport (ADVAPI, CharSet = CharSet.Unicode, SetLastError = true)] - static extern int RegOpenKeyEx (UIntPtr hKey, string subKey, uint reserved, uint sam, out UIntPtr phkResult); - - [DllImport (ADVAPI, CharSet = CharSet.Unicode, SetLastError = true)] - static extern int RegQueryValueExW (UIntPtr hKey, string lpValueName, int lpReserved, out uint lpType, - StringBuilder lpData, ref uint lpcbData); - - [DllImport (ADVAPI, CharSet = CharSet.Unicode, SetLastError = true)] - static extern int RegSetValueExW (UIntPtr hKey, string lpValueName, int lpReserved, - uint dwType, string data, uint cbData); - - [DllImport (ADVAPI, CharSet = CharSet.Unicode, SetLastError = true)] - static extern int RegSetValueExW (UIntPtr hKey, string lpValueName, int lpReserved, - uint dwType, IntPtr data, uint cbData); - - [DllImport (ADVAPI, CharSet = CharSet.Unicode, SetLastError = true)] - static extern int RegCreateKeyEx (UIntPtr hKey, string subKey, uint reserved, string @class, uint options, - uint samDesired, IntPtr lpSecurityAttributes, out UIntPtr phkResult, out Disposition lpdwDisposition); - - [DllImport ("advapi32.dll", SetLastError = true)] - static extern int RegCloseKey (UIntPtr hKey); - - public static string GetValueString (UIntPtr key, string subkey, string valueName, Wow64 wow64) - { - UIntPtr regKeyHandle; - uint sam = (uint)Rights.QueryValue + (uint)wow64; - if (RegOpenKeyEx (key, subkey, 0, sam, out regKeyHandle) != 0) - return null; - - try { - uint type; - var sb = new StringBuilder (2048); - uint cbData = (uint)sb.Capacity; - if (RegQueryValueExW (regKeyHandle, valueName, 0, out type, sb, ref cbData) == 0) { - return sb.ToString (); - } - return null; - } finally { - RegCloseKey (regKeyHandle); - } - } - - public static void SetValueString (UIntPtr key, string subkey, string valueName, string value, Wow64 wow64) - { - UIntPtr regKeyHandle; - uint sam = (uint)(Rights.CreateSubKey | Rights.SetValue) + (uint)wow64; - uint options = (uint)Options.NonVolatile; - Disposition disposition; - if (RegCreateKeyEx (key, subkey, 0, null, options, sam, IntPtr.Zero, out regKeyHandle, out disposition) != 0) { - throw new Exception ("Could not open or create key"); - } - - try { - uint type = (uint)ValueType.String; - uint lenBytesPlusNull = ((uint)value.Length + 1) * 2; - var result = RegSetValueExW (regKeyHandle, valueName, 0, type, value, lenBytesPlusNull); - if (result != 0) - throw new Exception (string.Format ("Error {0} setting registry '{1}{2}' with value '{3}'='{4}'", - result, key, subkey, valueName, value)); - } finally { - RegCloseKey (regKeyHandle); - } - } - - [Flags] - enum Rights : uint - { - None = 0, - QueryValue = 0x0001, - SetValue = 0x0002, - CreateSubKey = 0x0004, - EnumerateSubKey = 0x0008, - } - - enum Options - { - BackupRestore = 0x00000004, - CreateLink = 0x00000002, - NonVolatile = 0x00000000, - Volatile = 0x00000001, - } - - public enum Wow64 : uint - { - Key64 = 0x0100, - Key32 = 0x0200, - } - - enum ValueType : uint - { - None = 0, //REG_NONE - String = 1, //REG_SZ - UnexpandedString = 2, //REG_EXPAND_SZ - Binary = 3, //REG_BINARY - DWord = 4, //REG_DWORD - DWordLittleEndian = 4, //REG_DWORD_LITTLE_ENDIAN - DWordBigEndian = 5, //REG_DWORD_BIG_ENDIAN - Link = 6, //REG_LINK - MultiString = 7, //REG_MULTI_SZ - ResourceList = 8, //REG_RESOURCE_LIST - FullResourceDescriptor = 9, //REG_FULL_RESOURCE_DESCRIPTOR - ResourceRequirementsList = 10, //REG_RESOURCE_REQUIREMENTS_LIST - QWord = 11, //REG_QWORD - QWordLittleEndian = 11, //REG_QWORD_LITTLE_ENDIAN - } - - enum Disposition : uint - { - CreatedNewKey = 0x00000001, - OpenedExistingKey = 0x00000002, - } - } -} From e25f80e2c795a1877bbb1a7628a2b0b1d521e732 Mon Sep 17 00:00:00 2001 From: Jonathan Peppers Date: Tue, 9 Jun 2026 12:20:24 -0500 Subject: [PATCH 2/3] [cleanup] Remove dead types from Xamarin.Installer.AndroidSDK and Xamarin.AndroidTools - Delete Utils.cs (Xamarin.AndroidTools): all members unused by consumers. - Delete CustomVSAndroidLicensesStorage.cs: unused. - Delete SystemImageSpec.cs: unused. - Delete IAndroidArchive.cs and IAndroidComponentDescriptor.cs: only referenced by each other, no implementers. All five downstream csprojs build cleanly. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/Xamarin.AndroidTools/Utils.cs | 111 ------------------ .../Common/CustomVSAndroidLicensesStorage.cs | 49 -------- .../Common/IAndroidArchive.cs | 15 --- .../Common/IAndroidComponentDescriptor.cs | 29 ----- .../SystemImageSpec.cs | 30 ----- 5 files changed, 234 deletions(-) delete mode 100644 src/Xamarin.AndroidTools/Utils.cs delete mode 100644 src/Xamarin.Installer.AndroidSDK/Xamarin.Installer.AndroidSDK/Common/CustomVSAndroidLicensesStorage.cs delete mode 100644 src/Xamarin.Installer.AndroidSDK/Xamarin.Installer.AndroidSDK/Common/IAndroidArchive.cs delete mode 100644 src/Xamarin.Installer.AndroidSDK/Xamarin.Installer.AndroidSDK/Common/IAndroidComponentDescriptor.cs delete mode 100644 src/Xamarin.Installer.AndroidSDK/Xamarin.Installer.AndroidSDK/SystemImageSpec.cs diff --git a/src/Xamarin.AndroidTools/Utils.cs b/src/Xamarin.AndroidTools/Utils.cs deleted file mode 100644 index d9125cfe4a9..00000000000 --- a/src/Xamarin.AndroidTools/Utils.cs +++ /dev/null @@ -1,111 +0,0 @@ -// -// Utils.cs -// -// Author: -// Andreia Gaita -// -// Copyright (c) 2012 Xamarin Inc. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -using System; - -namespace Xamarin.AndroidTools -{ - [Obsolete] - public static class Utils - { - - /// - /// Converts a framework version (2.2 or v2.2) to an Android API Level (8) - /// - [Obsolete("Use AndroidVersion.TryOSVersionToApiLevel")] - public static int FrameworkVersionToApiLevel (string version) - { - version = version.TrimStart ('v'); - - switch (version) { - case "1.6": - return 4; - case "2.0": - return 5; - case "2.0.1": - return 6; - case "2.1": - return 7; - case "2.2": - return 8; - case "2.3": - return 10; - case "3.0": - return 11; - case "3.1": - return 12; - case "3.2": - return 13; - case "4.0": - return 14; - case "4.0.3": - return 15; - case "4.1": - return 16; - case "4.2": - return 17; - case "4.3": - return 18; - case "4.4": - return 19; - case "4.4.87": - return 20; - case "5.0": - return 21; - } - - return -1; - } - - /// - /// Gets all the api levels we are currently supporting (shipping assemblies for) - /// - /// - [Obsolete("Use MonoDroidSdk.SupportedApiLevels")] - public static int[] SupportedApiLevels { - get { return MonoDroidSdk.SupportedApiLevels; } - } - - /// - /// Gets the path to Google's Android SDK - /// - [Obsolete("Use AndroidSdk.AndroidSdkPath")] - public static string GetAndroidSdkPath () - { - return AndroidSdk.AndroidSdkPath; - } - - /// - /// Sets the user specified path to Google's Android SDK - /// - /// - [Obsolete("Use AndroidSdk.SetPreferredAndroidSdkPath")] - public static void SetAndroidSdkPath (string path) - { - AndroidSdk.SetPreferredAndroidSdkPath (path); - } - } -} diff --git a/src/Xamarin.Installer.AndroidSDK/Xamarin.Installer.AndroidSDK/Common/CustomVSAndroidLicensesStorage.cs b/src/Xamarin.Installer.AndroidSDK/Xamarin.Installer.AndroidSDK/Common/CustomVSAndroidLicensesStorage.cs deleted file mode 100644 index 1f31a937aae..00000000000 --- a/src/Xamarin.Installer.AndroidSDK/Xamarin.Installer.AndroidSDK/Common/CustomVSAndroidLicensesStorage.cs +++ /dev/null @@ -1,49 +0,0 @@ -using System; -using System.IO; -using System.Linq; -using System.Security.Cryptography; -using System.Text; - -namespace Xamarin.Installer.AndroidSDK.Common -{ - public class CustomVSAndroidLicensesStorage : AndroidLicensesStorage - { - protected override string GetLicensesPath(string androidSdkPath) - { - if (string.IsNullOrWhiteSpace(androidSdkPath) || !Directory.Exists(androidSdkPath)) - { - return null; - } - - var androidSdkId = GetLicensesLocalStorageIdFor(androidSdkPath); - var winHome = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); - return Path.Combine(winHome, "Xamarin", "Mono for Android", "Licenses", androidSdkId); - } - - string GetLicensesLocalStorageIdFor(string androidSdkPath) - { - using (var hashAlgorithm = SHA256.Create()) - { - var bytes = Encoding.UTF8.GetBytes(androidSdkPath.ToLowerInvariant()); - var hash = string.Concat(hashAlgorithm.ComputeHash(bytes).Select(x => x.ToString("x2"))); - return hash; - } - } - - protected override string GetLicenseHash(License license) - { - if (string.IsNullOrEmpty(license?.Text)) - { - return null; - } - - var content = string.IsNullOrEmpty(license.Text) ? license.ID : license.Text; - using (var hashAlgorithm = SHA256.Create()) - { - var bytes = Encoding.UTF8.GetBytes(content.ToLowerInvariant()); - var hash = string.Concat(hashAlgorithm.ComputeHash(bytes).Select(x => x.ToString("x2"))); - return hash; - } - } - } -} diff --git a/src/Xamarin.Installer.AndroidSDK/Xamarin.Installer.AndroidSDK/Common/IAndroidArchive.cs b/src/Xamarin.Installer.AndroidSDK/Xamarin.Installer.AndroidSDK/Common/IAndroidArchive.cs deleted file mode 100644 index 23892f3df40..00000000000 --- a/src/Xamarin.Installer.AndroidSDK/Xamarin.Installer.AndroidSDK/Common/IAndroidArchive.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; - -namespace Xamarin.Installer.AndroidSDK.Common -{ - interface IAndroidArchive - { - string OS { get; } - uint OSBits { get; } - string Arch { get; } - uint Size { get; } - string Checksum { get; } - string ChecksumType { get; } - Uri Url { get; } - } -} diff --git a/src/Xamarin.Installer.AndroidSDK/Xamarin.Installer.AndroidSDK/Common/IAndroidComponentDescriptor.cs b/src/Xamarin.Installer.AndroidSDK/Xamarin.Installer.AndroidSDK/Common/IAndroidComponentDescriptor.cs deleted file mode 100644 index 4f82fef7d7d..00000000000 --- a/src/Xamarin.Installer.AndroidSDK/Xamarin.Installer.AndroidSDK/Common/IAndroidComponentDescriptor.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Reflection; -using System.Text; -using System.Xml; - -using Xamarin.Installer.Common; - -namespace Xamarin.Installer.AndroidSDK.Common -{ - interface IAndroidComponentDescriptor - { - Uri BaseURL { get; } - AndroidRevision Revision { get; } - string PreviewRevision { get; } - string Description { get; } - Uri DescriptionUrl { get; } - string UsesLicense { get; } - bool IsObsolete { get; } - bool IsPreview { get; } - IList AddonsInfo { get; } - - string Name { get; } - bool IsEssential { get; } - - IAndroidComponent CreateComponent(AndroidSDKInstaller installer); - IAndroidArchive GetArchive(string os, string arch, uint osbits, bool quiet = false); - } -} diff --git a/src/Xamarin.Installer.AndroidSDK/Xamarin.Installer.AndroidSDK/SystemImageSpec.cs b/src/Xamarin.Installer.AndroidSDK/Xamarin.Installer.AndroidSDK/SystemImageSpec.cs deleted file mode 100644 index 928489743e0..00000000000 --- a/src/Xamarin.Installer.AndroidSDK/Xamarin.Installer.AndroidSDK/SystemImageSpec.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -using Xamarin.Installer.AndroidSDK.Common; - -namespace Xamarin.Installer.AndroidSDK -{ - /// - /// Specification of a single Android SDK System Image - /// - public class SystemImageSpec - { - /// - /// ABI of the system image - /// - public AndroidSystemImageAbi ABI { get; set; } - - /// - /// Tag (flavor) of the System Image (e.g. 'default', 'google_apis' etc - the list is - /// not defined anywhere, the only source of information is the Android SDK itself, namely - /// the 'system-images' directory off the Android SDK installation root. Subdirectories of - /// that directory correspond to the Android SDK platforms and their subdirectories, in turn, - /// are the names of the tags you can use here. - /// - public PackageTag Tag { get; set; } - } -} From 52b9d440e6bf60a28055c42f8fa4a461feced1a1 Mon Sep 17 00:00:00 2001 From: Jonathan Peppers Date: Tue, 9 Jun 2026 12:32:58 -0500 Subject: [PATCH 3/3] [cleanup] Remove additional dead types - Delete AmIntentCommandParser.cs and the matching ExecutionConfiguration(string, string) constructor: only consumer (RunActivity.cs) calls the (string, AmIntentCommand) overload. - Remove IProgressMonitorFactory interface from IProgressMonitor.cs: no callers anywhere in the repo. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../Debugging/AmIntentCommandParser.cs | 303 ------------------ .../Debugging/ExecutionConfiguration.cs | 13 - .../IProgressMonitor.cs | 14 - 3 files changed, 330 deletions(-) delete mode 100644 src/Xamarin.AndroidTools/Debugging/AmIntentCommandParser.cs diff --git a/src/Xamarin.AndroidTools/Debugging/AmIntentCommandParser.cs b/src/Xamarin.AndroidTools/Debugging/AmIntentCommandParser.cs deleted file mode 100644 index 104ed74674e..00000000000 --- a/src/Xamarin.AndroidTools/Debugging/AmIntentCommandParser.cs +++ /dev/null @@ -1,303 +0,0 @@ -// -// AmIntentCommandParser.cs -// -// Author: -// Greg Munn -// -// Copyright (c) 2016 Xamarin Inc -// - -using System; -using System.Collections.Generic; -using System.Linq; -using Mono.AndroidTools; -using Mono.AndroidTools.Util; - -namespace Xamarin.AndroidTools.Debugging -{ - public static class AmIntentCommandParser - { - public static AmIntentCommand Parse(string command, string packageName) - { - string[] args; - if (!ProcessArgumentBuilder.TryParse(command, out args)) - throw new ArgumentException(string.Format("Command '{0}' could not be parsed", command)); - - if (args.Length < 2) - throw new ArgumentException(string.Format("Command '{0}' does not have the correct number of arguments", command)); - - if (args[0] != "am") - throw new ArgumentException(string.Format("Command '{0}' does not start with `am`", command)); - - AmOptions options; - switch (args[1]) { - case "start": - options = new AmStartOptions(packageName); - - break; - case "startservice": - options = new AmStartServiceOptions(packageName); - - break; - case "broadcast": - options = new AmBroadcastOptions(packageName); - - break; - default: - throw new NotSupportedException(string.Format("Unsupported `am {0}` command", args[1])); - } - - var optSet = options.GetOptionSet(); - var optionArgs = args.Skip(2).ToArray(); - - var remainingArgs = optSet.Parse(optionArgs); - options.HandleRemainingArgs(remainingArgs); - - return options.Command; - } - - public static ExtraDataUri ParseDataUri(string v) - { - return new ExtraDataUri(v); - } - - public static ExtraComponentName ParseComponentName(string v) - { - return new ExtraComponentName(v); - } - - public static long ParseLong(string v) - { - return long.Parse(v); - } - - public static ExtraFloat ParseFloat(string v) - { - return new ExtraFloat(v); - } - - public static int[] ParseIntArray(string v) - { - if (string.IsNullOrEmpty(v)) - return new int[0]; - - var values = v.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries); - var result = new int[values.Length]; - for (int i = 0; i < values.Length; i++) - { - result[i] = int.Parse(values[i]); - } - - return result; - } - - public static long[] ParseLongArray(string v) - { - if (string.IsNullOrEmpty(v)) - return new long[0]; - - var values = v.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries); - var result = new long[values.Length]; - for (int i = 0; i < values.Length; i++) - { - result[i] = ParseLong(values[i]); - } - - return result; - } - - public static ExtraFloat[] ParseFloatArray(string v) - { - if (string.IsNullOrEmpty(v)) - return new ExtraFloat[0]; - - var values = v.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries); - var result = new ExtraFloat[values.Length]; - for (int i = 0; i < values.Length; i++) - { - result[i] = ParseFloat(values[i]); - } - - return result; - } - - public static bool ParseExtraBool(string v) - { - if (string.Equals(v, "true", StringComparison.OrdinalIgnoreCase)) - { - return true; - } - - if (string.Equals(v, "false", StringComparison.OrdinalIgnoreCase)) - { - return false; - } - - if (string.Equals(v, "1", StringComparison.OrdinalIgnoreCase)) - { - return true; - } - - if (string.Equals(v, "0", StringComparison.OrdinalIgnoreCase)) - { - return false; - } - - throw new FormatException("coud not parse boolean value"); - } - - abstract class AmOptions - { - public AmIntentCommand Command { get; protected set; } - public abstract Mono.Options.OptionSet GetOptionSet(); - public virtual void HandleRemainingArgs(List args) - { - if (args.Count > 0) { - this.Command.Intent = args[0]; - } - } - - protected void AddIntentOptions(Mono.Options.OptionSet options) - { - // intent options - options.Add("n=", "Component", s => this.Command.Component = s); - options.Add("a=", "Action", s => this.Command.Action = s); - options.Add("d=", "Data Uri", s => this.Command.DataUri = s); - options.Add("c=", "Category", s => this.Command.Categories.Add(s)); - options.Add("t=", "Mime Type", s => this.Command.MimeType = s); - // strictly speaking we should also support -p here, but we don't because of conflicts with the use of - // packageName for fast dev property settings - - options.Add("selector", "Selector", s => this.Command.Selector = true); - - } - - protected void AddFlagsOptions(Mono.Options.OptionSet options) - { - options.Add("f=", (k) => { throw new NotSupportedException("-f is not supported, use individual flag arguments"); }); - - options.Add("grant-read-uri-permission", (k) => this.Command.Flags = this.Command.Flags | IntentFlag.GrantReadUriPermission); - options.Add("grant-write-uri-permission", (k) => this.Command.Flags = this.Command.Flags | IntentFlag.GrantWriteUriPermission); - options.Add("debug-log-resolution", (k) => this.Command.Flags = this.Command.Flags | IntentFlag.DebugLogResolution); - options.Add("exclude-stopped-packages", (k) => this.Command.Flags = this.Command.Flags | IntentFlag.ExcludeStoppedPackages); - options.Add("include-stopped-packages", (k) => this.Command.Flags = this.Command.Flags | IntentFlag.IncludeStoppedPackages); - options.Add("activity-brought-to-front", (k) => this.Command.Flags = this.Command.Flags | IntentFlag.ActivityBroughtToFront); - options.Add("activity-clear-top", (k) => this.Command.Flags = this.Command.Flags | IntentFlag.ActivityClearTop); - options.Add("activity-clear-when-task-reset", (k) => this.Command.Flags = this.Command.Flags | IntentFlag.ActivityClearWhenTaskReset); - options.Add("activity-exclude-from-recents", (k) => this.Command.Flags = this.Command.Flags | IntentFlag.ActivityExcludeFromRecents); - options.Add("activity-launched-from-history", (k) => this.Command.Flags = this.Command.Flags | IntentFlag.ActivityLaunchedFromHistory); - options.Add("activity-multiple-task", (k) => this.Command.Flags = this.Command.Flags | IntentFlag.ActvityMultipleTask); - options.Add("activity-no-animation", (k) => this.Command.Flags = this.Command.Flags | IntentFlag.ActivityNoAnimation); - options.Add("activity-no-history", (k) => this.Command.Flags = this.Command.Flags | IntentFlag.ActivityNoHistory); - options.Add("activity-no-user-action", (k) => this.Command.Flags = this.Command.Flags | IntentFlag.ActivityNoUserAction); - options.Add("activity-previous-is-top", (k) => this.Command.Flags = this.Command.Flags | IntentFlag.ActivityPreviousIsTop); - options.Add("activity-reorder-to-front", (k) => this.Command.Flags = this.Command.Flags | IntentFlag.ActivityReorderToFront); - options.Add("activity-reset-task-if-needed", (k) => this.Command.Flags = this.Command.Flags | IntentFlag.ActivityResetTaskIfNeeded); - options.Add("activity-single-top", (k) => this.Command.Flags = this.Command.Flags | IntentFlag.ActivitySingleTop); - options.Add("activity-clear-task", (k) => this.Command.Flags = this.Command.Flags | IntentFlag.ActivityClearTask); - options.Add("activity-task-on-home", (k) => this.Command.Flags = this.Command.Flags | IntentFlag.ActivityTaskOnHome); - options.Add("receiver-registered-only", (k) => this.Command.Flags = this.Command.Flags | IntentFlag.ReceiverRegisteredOnly); - options.Add("receiver-replace-pending", (k) => this.Command.Flags = this.Command.Flags | IntentFlag.ReceiverReplacePending); - } - - protected void AddExtraOptions(Mono.Options.OptionSet options) - { - options.Add("esn=", "Extra Null", (k) => this.Command.Extras.Add(k, null)); - options.Add("e|es=", "Extra String", (k, v) => this.Command.Extras.Add(k, v)); - options.Add("ez=", "Extra Bool", (k, v) => this.Command.Extras.Add(k, ParseExtraBool(v))); - options.Add("ei=", "Extra Int", (k, v) => this.Command.Extras.Add(k, int.Parse(v))); - options.Add("el=", "Extra Long", (k, v) => this.Command.Extras.Add(k, ParseLong(v))); - options.Add("ef=", "Extra Float", (k, v) => this.Command.Extras.Add(k, ParseFloat(v))); - options.Add("eu=", "Extra Uri", (k, v) => this.Command.Extras.Add(k, ParseDataUri(v))); - options.Add("ecn=", "Extra Component Name", (k, v) => this.Command.Extras.Add(k, ParseComponentName(v))); - - // extras that take an array - options.Add("eia=", "Extra Int Array", (k, v) => this.Command.Extras.Add(k, ParseIntArray(v))); - options.Add("ela=", "Extra Long Array", (k, v) => this.Command.Extras.Add(k, ParseLongArray(v))); - options.Add("efa=", "Extra Float Array", (k, v) => this.Command.Extras.Add(k, ParseFloatArray(v))); - } - } - - class AmStartOptions : AmOptions - { - readonly AmStartCommand command; - - public AmStartOptions(string packageName) - { - this.Command = this.command = new AmStartCommand(); - this.command.PackageName = packageName; - this.command.Extras = new Dictionary(); - this.command.Categories = new List(); - } - - public override Mono.Options.OptionSet GetOptionSet() - { - var options = new Mono.Options.OptionSet { - // start options - { "D", "Enable Debugging", s => this.command.EnableDebugging = true }, - { "W", "Wait For Launch", s => this.command.Wait = true }, - { "start-profiler=", "Profiler Output", s => this.command.ProfilerOutputPath = s }, - { "R=", "Repeat Launch", s => this.command.Repeat = int.Parse(s) }, - { "S", "Force Stop", s => this.command.ForceStop = true }, - { "opengl-trace", "Open GL Trace", s => this.command.EnableOpenGLTracing = true }, - { "user=", "User Id", s => this.command.User = s }, - }; - - AddIntentOptions(options); - AddExtraOptions(options); - AddFlagsOptions(options); - return options; - } - } - - class AmStartServiceOptions : AmOptions - { - readonly AmStartServiceCommand command; - - public AmStartServiceOptions(string packageName) - { - this.Command = this.command = new AmStartServiceCommand(); - this.command.PackageName = packageName; - this.command.Extras = new Dictionary(); - this.command.Categories = new List(); - } - - public override Mono.Options.OptionSet GetOptionSet() - { - var options = new Mono.Options.OptionSet { - { "user=", "User Id", s => this.command.User = s }, - }; - - AddIntentOptions(options); - AddExtraOptions(options); - AddFlagsOptions(options); - return options; - } - } - - class AmBroadcastOptions : AmOptions - { - readonly AmBroadcastCommand command; - - public AmBroadcastOptions(string packageName) - { - this.Command = this.command = new AmBroadcastCommand(); - this.command.PackageName = packageName; - this.command.Extras = new Dictionary(); - this.command.Categories = new List(); - } - - public override Mono.Options.OptionSet GetOptionSet() - { - var options = new Mono.Options.OptionSet { - { "user=", "User Id", s => this.command.User = s }, - }; - - AddIntentOptions(options); - AddExtraOptions(options); - AddFlagsOptions(options); - return options; - } - } - } -} \ No newline at end of file diff --git a/src/Xamarin.AndroidTools/Debugging/ExecutionConfiguration.cs b/src/Xamarin.AndroidTools/Debugging/ExecutionConfiguration.cs index 728a7b8ade5..e1062baf965 100644 --- a/src/Xamarin.AndroidTools/Debugging/ExecutionConfiguration.cs +++ b/src/Xamarin.AndroidTools/Debugging/ExecutionConfiguration.cs @@ -27,19 +27,6 @@ public ExecutionConfiguration(string packageName, AmIntentCommand runCommand) this.Debugger = new DebuggerOptions(); } - public ExecutionConfiguration(string packageName, string runCommand) - { - if (string.IsNullOrEmpty(packageName)) - throw new ArgumentException(nameof(packageName)); - - this.PackageName = packageName; - this.Debugger = new DebuggerOptions(); - - if (!string.IsNullOrEmpty(runCommand)) { - this.RunCommand = AmIntentCommandParser.Parse(runCommand, packageName); - } - } - /// /// Gets the name of the package that is being debugged. This is needed to set FastDev property files for /// devices that fail to the debug properties corectly diff --git a/src/Xamarin.Installer.AndroidSDK/Xamarin.Installer.AndroidSDK/IProgressMonitor.cs b/src/Xamarin.Installer.AndroidSDK/Xamarin.Installer.AndroidSDK/IProgressMonitor.cs index d8d9fcdc9c3..2172547f99e 100644 --- a/src/Xamarin.Installer.AndroidSDK/Xamarin.Installer.AndroidSDK/IProgressMonitor.cs +++ b/src/Xamarin.Installer.AndroidSDK/Xamarin.Installer.AndroidSDK/IProgressMonitor.cs @@ -12,20 +12,6 @@ namespace Xamarin.Installer.AndroidSDK.Manager { - /// - /// The Progress monitor factory interface is used by to - /// create installation progress monitors on demand. - /// - public interface IProgressMonitorFactory - { - /// - /// Creates a progress monitor to observe the SDK Manager installation progress. - /// - /// The progress monitor. - /// The SDK Manager will create a new progress monitor for each installation process. - IProgressMonitor CreateProgressMonitor (); - } - /// /// The cancellable progress monitor can cancel a running operation. ///