////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public AndroidProcess(AndroidDevice device, string name, uint pid, uint ppid, string user)
        {
            if (device == null)
            {
                throw new ArgumentNullException("device");
            }

            if (string.IsNullOrEmpty(name))
            {
                throw new ArgumentNullException("name");
            }

            if (string.IsNullOrEmpty(user))
            {
                throw new ArgumentNullException("user");
            }

            HostDevice = device;

            Name = name;

            Pid = pid;

            ParentPid = ppid;

            User = user;
        }
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    public AndroidProcess (AndroidDevice device, string name, uint pid, uint ppid, string user)
    {
      if (device == null)
      {
        throw new ArgumentNullException ("device");
      }

      if (string.IsNullOrEmpty (name))
      {
        throw new ArgumentNullException ("name");
      }

      if (string.IsNullOrEmpty (user))
      {
        throw new ArgumentNullException ("user");
      }

      HostDevice = device;

      Name = name;

      Pid = pid;

      ParentPid = ppid;

      User = user;
    }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        public static SyncRedirectProcess AdbCommand(AndroidDevice target, string command, string arguments)
        {
            LoggingUtils.Print (string.Format ("[AndroidDevice] AdbCommand: Target={0} Cmd={1} Args={2}", target.ID, command, arguments));

              SyncRedirectProcess adbCommand = new SyncRedirectProcess (AndroidSettings.SdkRoot + @"\platform-tools\adb.exe", string.Format ("-s {0} {1} {2}", target.ID, command, arguments));

              return adbCommand;
        }
Exemple #4
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public static AsyncRedirectProcess AdbCommandAsync(AndroidDevice target, string command, string arguments)
        {
            LoggingUtils.Print(string.Format("[AndroidDevice] AdbCommandAsync: Target={0} Cmd={1} Args={2}", target.ID, command, arguments));

            AsyncRedirectProcess adbCommand = new AsyncRedirectProcess(AndroidSettings.SdkRoot + @"\platform-tools\adb.exe", string.Format("-s {0} {1} {2}", target.ID, command, arguments));

            return(adbCommand);
        }
Exemple #5
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public static bool IsDeviceConnected(AndroidDevice queryDevice)
        {
            LoggingUtils.PrintFunction();

            lock (m_updateLockMutex)
            {
                return(m_connectedDevices.ContainsKey(queryDevice.ID));
            }
        }
Exemple #6
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public static AndroidDevice [] GetConnectedDevices()
        {
            lock (m_updateLockMutex)
            {
                AndroidDevice [] deviceArray = new AndroidDevice [m_connectedDevices.Count];

                m_connectedDevices.Values.CopyTo(deviceArray, 0);

                return(deviceArray);
            }
        }
Exemple #7
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public static AndroidDevice GetConnectedDeviceById(string id)
        {
            AndroidDevice device = null;

            lock (m_updateLockMutex)
            {
                m_connectedDevices.TryGetValue(id, out device);
            }

            return(device);
        }
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    public static void Refresh ()
    {
      LoggingUtils.PrintFunction ();

      lock (m_updateLockMutex)
      {
        // 
        // Start an ADB instance, if required.
        // 

        using (SyncRedirectProcess adbStartServer = new SyncRedirectProcess (AndroidSettings.SdkRoot + @"\platform-tools\adb.exe", "start-server"))
        {
          adbStartServer.StartAndWaitForExit (30000);
        }

        using (SyncRedirectProcess adbDevices = new SyncRedirectProcess (AndroidSettings.SdkRoot + @"\platform-tools\adb.exe", "devices"))
        {
          adbDevices.StartAndWaitForExit (30000);

          // 
          // Parse 'devices' output, skipping headers and potential 'start-server' output.
          // 

          Dictionary<string, string> currentAdbDevices = new Dictionary<string, string> ();

          LoggingUtils.Print (string.Format ("[AndroidAdb] Devices output: {0}", adbDevices.StandardOutput));

          if (!String.IsNullOrEmpty (adbDevices.StandardOutput))
          {
            string [] deviceOutputLines = adbDevices.StandardOutput.Replace ("\r", "").Split (new char [] { '\n' });

            foreach (string line in deviceOutputLines)
            {
              if (Regex.IsMatch (line, "^[A-Za-z0-9.:\\-]+[\t][a-z]+$"))
              {
                string [] segments = line.Split (new char [] { '\t' });

                string deviceName = segments [0];

                string deviceType = segments [1];

                currentAdbDevices.Add (deviceName, deviceType);
              }
            }
          }

          // 
          // First identify any previously tracked devices which aren't in 'devices' output.
          // 

          HashSet<string> disconnectedDevices = new HashSet<string> ();

          foreach (string key in m_connectedDevices.Keys)
          {
            string deviceName = (string) key;

            if (!currentAdbDevices.ContainsKey (deviceName))
            {
              disconnectedDevices.Add (deviceName);
            }
          }

          // 
          // Identify whether any devices have changed state; connected/persisted/disconnected.
          // 

          foreach (KeyValuePair <string, string> devicePair in currentAdbDevices)
          {
            string deviceName = devicePair.Key;

            string deviceType = devicePair.Value;

            if (deviceType.Equals ("offline"))
            {
              disconnectedDevices.Add (deviceName);
            }
            else if (deviceType.Equals ("unauthorized"))
            {
              // User needs to allow USB debugging.
            }
            else
            {
              AndroidDevice connectedDevice;

              if (m_connectedDevices.TryGetValue (deviceName, out connectedDevice))
              {
                // 
                // Device is pervasive. Refresh internal properties.
                // 

                LoggingUtils.Print (string.Format ("[AndroidAdb] Device pervaded: {0} - {1}", deviceName, deviceType));

                connectedDevice.Refresh ();

                foreach (IStateListener deviceListener in m_registeredDeviceStateListeners)
                {
                  deviceListener.DevicePervasive (connectedDevice);
                }
              }
              else
              {
                // 
                // Device connected.
                // 

                LoggingUtils.Print (string.Format ("[AndroidAdb] Device connected: {0} - {1}", deviceName, deviceType));

                connectedDevice = new AndroidDevice (deviceName);

                connectedDevice.Refresh ();

                m_connectedDevices.Add (deviceName, connectedDevice);

                foreach (IStateListener deviceListener in m_registeredDeviceStateListeners)
                {
                  deviceListener.DeviceConnected (connectedDevice);
                }
              }
            }
          }

          // 
          // Finally, handle device disconnection.
          // 

          foreach (string deviceName in disconnectedDevices)
          {
            AndroidDevice disconnectedDevice;

            if (m_connectedDevices.TryGetValue (deviceName, out disconnectedDevice))
            {
              LoggingUtils.Print (string.Format ("[AndroidAdb] Device disconnected: {0}", deviceName));

              m_connectedDevices.Remove (deviceName);

              foreach (IStateListener deviceListener in m_registeredDeviceStateListeners)
              {
                deviceListener.DeviceDisconnected (disconnectedDevice);
              }
            }
          }
        }
      }
    }
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    public static bool IsDeviceConnected (AndroidDevice queryDevice)
    {
      LoggingUtils.PrintFunction ();

      lock (m_updateLockMutex)
      {
        return m_connectedDevices.ContainsKey (queryDevice.ID);
      }
    }
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    public static AndroidDevice [] GetConnectedDevices ()
    {
      lock (m_updateLockMutex)
      {
        AndroidDevice [] deviceArray = new AndroidDevice [m_connectedDevices.Count];

        m_connectedDevices.Values.CopyTo (deviceArray, 0);

        return deviceArray;
      }
    }
Exemple #11
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public static void Refresh()
        {
            LoggingUtils.PrintFunction();

            lock (m_updateLockMutex)
            {
                //
                // Start an ADB instance, if required.
                //

                using (SyncRedirectProcess adbStartServer = new SyncRedirectProcess(AndroidSettings.SdkRoot + @"\platform-tools\adb.exe", "start-server"))
                {
                    adbStartServer.StartAndWaitForExit(30000);
                }

                using (SyncRedirectProcess adbDevices = new SyncRedirectProcess(AndroidSettings.SdkRoot + @"\platform-tools\adb.exe", "devices"))
                {
                    adbDevices.StartAndWaitForExit(30000);

                    //
                    // Parse 'devices' output, skipping headers and potential 'start-server' output.
                    //

                    Dictionary <string, string> currentAdbDevices = new Dictionary <string, string> ();

                    LoggingUtils.Print(string.Concat("[AndroidAdb] Devices output: ", adbDevices.StandardOutput));

                    if (!String.IsNullOrEmpty(adbDevices.StandardOutput))
                    {
                        string [] deviceOutputLines = adbDevices.StandardOutput.Replace("\r", "").Split(new char [] { '\n' });

                        foreach (string line in deviceOutputLines)
                        {
                            if (Regex.IsMatch(line, "^[A-Za-z0-9.:\\-]+[\t][A-Za-z]+$"))
                            {
                                string [] segments = line.Split(new char [] { '\t' });

                                string deviceName = segments [0];

                                string deviceType = segments [1];

                                currentAdbDevices.Add(deviceName, deviceType);
                            }
                        }
                    }

                    //
                    // First identify any previously tracked devices which aren't in 'devices' output.
                    //

                    HashSet <string> disconnectedDevices = new HashSet <string> ();

                    foreach (string key in m_connectedDevices.Keys)
                    {
                        string deviceName = (string)key;

                        if (!currentAdbDevices.ContainsKey(deviceName))
                        {
                            disconnectedDevices.Add(deviceName);
                        }
                    }

                    //
                    // Identify whether any devices have changed state; connected/persisted/disconnected.
                    //

                    foreach (KeyValuePair <string, string> devicePair in currentAdbDevices)
                    {
                        string deviceName = devicePair.Key;

                        string deviceType = devicePair.Value;

                        if (deviceType.Equals("offline", StringComparison.InvariantCultureIgnoreCase))
                        {
                            disconnectedDevices.Add(deviceName);
                        }
                        else if (deviceType.Equals("unauthorized", StringComparison.InvariantCultureIgnoreCase))
                        {
                            // User needs to allow USB debugging.
                        }
                        else
                        {
                            AndroidDevice connectedDevice;

                            if (m_connectedDevices.TryGetValue(deviceName, out connectedDevice))
                            {
                                //
                                // Device is pervasive. Refresh internal properties.
                                //

                                LoggingUtils.Print(string.Format("[AndroidAdb] Device pervaded: {0} - {1}", deviceName, deviceType));

                                connectedDevice.Refresh();

                                foreach (IStateListener deviceListener in m_registeredDeviceStateListeners)
                                {
                                    deviceListener.DevicePervasive(connectedDevice);
                                }
                            }
                            else
                            {
                                //
                                // Device connected.
                                //

                                LoggingUtils.Print(string.Format("[AndroidAdb] Device connected: {0} - {1}", deviceName, deviceType));

                                connectedDevice = new AndroidDevice(deviceName);

                                connectedDevice.Refresh();

                                m_connectedDevices.Add(deviceName, connectedDevice);

                                foreach (IStateListener deviceListener in m_registeredDeviceStateListeners)
                                {
                                    deviceListener.DeviceConnected(connectedDevice);
                                }
                            }
                        }
                    }

                    //
                    // Finally, handle device disconnection.
                    //

                    foreach (string deviceName in disconnectedDevices)
                    {
                        AndroidDevice disconnectedDevice;

                        if (m_connectedDevices.TryGetValue(deviceName, out disconnectedDevice))
                        {
                            LoggingUtils.Print(string.Concat("[AndroidAdb] Device disconnected: ", deviceName));

                            m_connectedDevices.Remove(deviceName);

                            foreach (IStateListener deviceListener in m_registeredDeviceStateListeners)
                            {
                                deviceListener.DeviceDisconnected(disconnectedDevice);
                            }
                        }
                    }
                }
            }
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        private void InstallApplicationAsync(AndroidDevice debuggingDevice, LaunchConfiguration launchConfig)
        {
            //
              // Asynchronous installation process, so the UI can be updated appropriately.
              //

              LoggingUtils.PrintFunction ();

              ManualResetEvent installCompleteEvent = new ManualResetEvent (false);

              Exception installFailedException = null;

              System.Threading.Thread asyncInstallApplicationThread = new System.Threading.Thread (delegate ()
              {
            try
            {
              string targetLocalApk = launchConfig ["TargetApk"];

              string targetRemoteTemporaryPath = "/data/local/tmp";

              string targetRemoteTemporaryFile = targetRemoteTemporaryPath + '/' + Path.GetFileName (targetLocalApk);

              bool keepData = launchConfig ["KeepAppData"].Equals ("true");

              string installerPackage = launchConfig ["InstallerPackage"];

              //
              // Construct 'am install' arguments for installing the application in a manner compatible with GDB.
              //
              // Note: Installations to /mnt/asec/ cause 'run-as' to fail regarding permissions.
              //

              StringBuilder installArgsBuilder = new StringBuilder ();

              installArgsBuilder.Append ("-f "); // install package on internal flash. (required for debugging)

              if (keepData)
              {
            installArgsBuilder.Append ("-r "); // reinstall an existing app, keeping its data.
              }

              if (!string.IsNullOrWhiteSpace (installerPackage))
              {
            installArgsBuilder.Append (string.Format (CultureInfo.InvariantCulture, "-i {0} ", installerPackage));
              }

              installArgsBuilder.Append (targetRemoteTemporaryFile);

              //
              // Explicitly install the target APK using 'pm' tool, as this allows more customisation.
              //
              //  1) APKs must already be on the device for this tool to work. We push these manually.
              //
              //  2) Installations can fail for various reasons; errors are reported thusly:
              //         pkg: /data/local/tmp/hello-gdbserver-Debug.apk
              //       Failure [INSTALL_FAILED_INVALID_URI]
              //

              m_debugConnectionService.LaunchDialogUpdate (string.Format (CultureInfo.InvariantCulture, "[adb:push] {0} {1}", targetLocalApk, targetRemoteTemporaryPath), false);

              debuggingDevice.Push (targetLocalApk, targetRemoteTemporaryPath);

              m_debugConnectionService.LaunchDialogUpdate (string.Format (CultureInfo.InvariantCulture, "[adb:shell:pm] {0} {1}", "install", installArgsBuilder.ToString ()), false);

              string installReport = debuggingDevice.Shell ("pm", "install " + installArgsBuilder.ToString (), int.MaxValue);

              if (!installReport.Contains ("Success"))
              {
            string sanitisedFailure = installReport;

            throw new InvalidOperationException (string.Format (CultureInfo.InvariantCulture, "[adb:shell:pm] install failed: {0}", sanitisedFailure));
              }

              m_debugConnectionService.LaunchDialogUpdate (string.Format (CultureInfo.InvariantCulture, "[adb:shell:rm] {0}", targetRemoteTemporaryFile), false);

              debuggingDevice.Shell ("rm", targetRemoteTemporaryFile);
            }
            catch (Exception e)
            {
              LoggingUtils.HandleException (e);

              installFailedException = e;

              throw;
            }
            finally
            {
              installCompleteEvent.Set ();
            }
              });

              asyncInstallApplicationThread.Start ();

              while (!installCompleteEvent.WaitOne (0))
              {
            Application.DoEvents ();

            System.Threading.Thread.Sleep (100);
              }

              if (installFailedException != null)
              {
            throw installFailedException;
              }
        }
 public DebuggerLogcatEvent (AndroidDevice device)
 {
   HostDevice = device;
 }
Exemple #14
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public static bool IsDeviceConnected(AndroidDevice queryDevice)
        {
            return(m_connectedDevices.ContainsKey(queryDevice.ID));
        }