Esempio n. 1
0
 private void InitAutumnBoxBasic()
 {
     Basic.Util.Settings.CreateNewWindow = Settings.Default.DisplayCmdWindow;
     try
     {
         logger.Info("killing other adb processes");
         TaskKill.Kill("adb.exe");
         logger.Info("autumnbox-adb-server is starting");
         var adbManager = AdbProviderFactory.Get(true).AdbManager;
         Adb.Load(adbManager);
         Adb.Server.Start();
         logger.Info($"autumnbox-adb-server is started at {Adb.Server.IP}:{Adb.Server.Port}");
     }
     catch (Exception e)
     {
         logger.Warn("there's some error happened while starting autumnbox-adb-server", e);
         App.Current.Dispatcher.Invoke(() =>
         {
             new AdbFailedWindow(e.Message)
             {
                 Owner = App.Current.MainWindow
             }.ShowDialog();
         });
         Fail();
     }
 }
Esempio n. 2
0
        public async Task GetDevicesAllStates()
        {
            // arrange
            var output = new List <string>
            {
                "List of devices attached",
                "PHILIPS W732\tdevice",
                "0123456789ABCDE\tunauthorized",
                "0123456789ABCDE\toffline"
            };
            var processManager = new TestProcessManager();

            processManager.AddProcess(output);
            var adb = new Adb(processManager);

            // act
            var devices = (await adb.GetDevices()).ToList();

            // assert
            processManager.Stub.AssertWasCalled(_ => _.CreateProcess(Arg <string> .Is.Anything, Arg <string> .Matches(commands => commands.Contains("devices"))));
            Assert.AreEqual(3, devices.Count);
            Assert.IsTrue(devices.ElementAt(0).State == DeviceState.Online);
            Assert.IsTrue(devices.ElementAt(1).State == DeviceState.Unauthorized);
            Assert.IsTrue(devices.ElementAt(2).State == DeviceState.Offline);
        }
Esempio n. 3
0
        private void apk_Click(object sender, RoutedEventArgs e)
        {
            AndroidController a       = AndroidController.Instance;
            string            caminho = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\SGEA\\SGEA.SGEA.apk";

            if (a.HasConnectedDevices)
            {
                caminho = "\"" + caminho + "\"";
                Device d = a.GetConnectedDevice(a.ConnectedDevices[0]);
                for (int i = 0; i < a.ConnectedDevices.Count; i++)
                {
                    d = a.GetConnectedDevice(a.ConnectedDevices[i]);
                    if (!d.SerialNumber.Contains("emulator"))
                    {
                        break;
                    }
                }
                var    ad = Adb.FormAdbShellCommand(d, false, "pm list packages SGEA.SGEA");
                string x  = Adb.ExecuteAdbCommand(ad);
                if (x != "package:SGEA.SGEA")
                {
                    var ade = Adb.FormAdbCommand(d, "install " + caminho);
                    Adb.ExecuteAdbCommand(ade);
                    Xceed.Wpf.Toolkit.MessageBox.Show("O aplicativo foi instalado com sucesso");
                }
                else
                {
                    Xceed.Wpf.Toolkit.MessageBox.Show("O aplicativo já está instalado");
                }
            }
            else
            {
                Xceed.Wpf.Toolkit.MessageBox.Show("Não há um celular Android conectado por USB");
            }
        }
        async Task Download()
        {
            var appData = Directory.CreateDirectory(adbDirectory);

            adb = new Adb(appData);
            //Check if exists in new Dirctory
            if (await IsAdbSetup())
            {
                return;
            }

            var adbZipPAth = Path.Combine(tempDirectory, "adb.zip");

            try
            {
                var client = new WebClient();
                await Task.Run(() => client.DownloadFile(new Uri("https://adbshell.com/upload/adb.zip"), adbZipPAth));

                Directory.CreateDirectory(platformToolsDirectory);
                System.IO.Compression.ZipFile.ExtractToDirectory(adbZipPAth, platformToolsDirectory);
                //sdkManager = new Adb(appData);
                var success = await IsAdbSetup();
            }
            catch (Exception ex)
            {
            }
            finally
            {
                if (File.Exists(adbZipPAth))
                {
                    File.Delete(adbZipPAth);
                }
            }
            //Lets download it!
        }
Esempio n. 5
0
        public async Task CreateUser_Error()
        {
            //arrange
            var processManager = new TestProcessManager();

            processManager.AddProcess(new[]
            {
                "Error: couldn't create User."
            }, "create-user");

            var adb = new Adb(processManager);

            //act
            try
            {
                await adb.SingleDevice.Shell.PackageManager.CreateUser("Test");

                //assert
                Assert.Fail();
            }
            catch (Exception ex)
            {
                Assert.IsInstanceOf <AdbException>(ex);
            }
        }
Esempio n. 6
0
 private void InitAutumnBoxBasic()
 {
     Basic.Util.Settings.CreateNewWindow = Settings.Default.DisplayCmdWindow;
     try
     {
         TaskKill.Kill("adb.exe");
         logger.Info("adb server starting");
         var adbManager = new ATMBWin32AdbManager();
         adbManager.Extract();
         Adb.Load(adbManager);
         Adb.Server.Start();
         logger.Info($"adb server started at {Adb.Server.IP}:{Adb.Server.Port}");
     }
     catch (Exception e)
     {
         logger.Warn("can not start adb server!", e);
         App.Current.Dispatcher.Invoke(() =>
         {
             new AdbFailedWindow(e.Message)
             {
                 Owner = App.Current.MainWindow
             }.ShowDialog();
         });
         Fail();
     }
 }
Esempio n. 7
0
        public override int Execute([NotNull] CommandContext context, [NotNull] DevicesListCommandSettings settings)
        {
            try
            {
                var adb     = new Adb(settings?.Home);
                var devices = adb.GetDevices();

                if ((settings?.Format ?? OutputFormat.None) == OutputFormat.None)
                {
                    OutputHelper.OutputTable(
                        devices,
                        new[] { "Serial", "Emulator", "Device", "Model", "Product" },
                        i => new[] { i.Serial, i.IsEmulator.ToString(), i.Device, i.Model, i.Product });
                }
                else
                {
                    OutputHelper.Output(devices, settings.Format);
                }
            }
            catch (SdkToolFailedExitException sdkEx)
            {
                Program.WriteException(sdkEx);
                return(1);
            }

            return(0);
        }
Esempio n. 8
0
        /// <summary>
        /// Dials (does not call) a phone number on the Android device
        /// </summary>
        /// <param name="phoneNumber">Phone number to dial</param>
        public void DialPhoneNumber(string phoneNumber)
        {
            if (this.device.State != DeviceState.ONLINE)
                return;

            AdbCommand adbCmd = Adb.FormAdbShellCommand(this.device, false, "service", "call", "phone", "1", "s16", phoneNumber);
            Adb.ExecuteAdbCommandNoReturn(adbCmd);
        }
Esempio n. 9
0
        private void Load()
        {
            LoggingStation.Instance.Work();
            Updater.CheckAndNotice();
            Statistics.Do();
            ui.Progress = 0;
            //如果设置在启动时打开调试窗口
            if (Settings.Default.ShowDebuggingWindowNextLaunch)
            {
                //打开调试窗口
                App.Current.Dispatcher.Invoke(() =>
                {
                    new LogWindow().Show();
                });
            }
            logger.Info("");
            logger.Info("======================");
            logger.Info($"Run as " + (Self.HaveAdminPermission ? "Admin" : "Normal user"));
            logger.Info($"AutumnBox version: {Self.Version}");
            logger.Info($"SDK version: {BuildInfo.SDK_VERSION}");
            logger.Info($"Windows version {Environment.OSVersion.Version}");
            logger.Info("======================");
            logger.Info("===loading===");
#if DEBUG
            Basic.Util.Debugging.LoggingStation.Logging += (s, e) =>
            {
                LoggingStation.Instance.Log(e.Tag, e.Level.ToString(), e.Text);
            };
#endif
            ui.Progress   = 30;
            ui.LoadingTip = App.Current.Resources["ldmsgStartAdb"].ToString();

            try
            {
                logger.Info("trying starts adb server ");
                Adb.DefaultLoad();
                logger.Info("adb server starts successed");
            }
            catch (AdbCommandFailedException e)
            {
                logger.Info("adb server starts failed");
                logger.Warn(e);
                ui.Progress   = 60;
                ui.LoadingTip = App.Current.Resources["ldmsgAdbServerFailed"].ToString();
                Thread.Sleep(10000);
                App.Current.Shutdown(e.ExitCode);
            }
            ui.Progress   = 60;
            ui.LoadingTip = App.Current.Resources["ldmsgLoadingExtensions"].ToString();
            OpenFrameworkManager.Init();
            OpenFxObserver.Instance.OnLoaded();
            ConnectedDevicesListener.Instance.Work();
            ui.Progress   = 100;
            ui.LoadingTip = "Enjoy!";
            Thread.Sleep(1 * 1000);
            logger.Info("===loaded===");
            ui.Finish();
        }
Esempio n. 10
0
        public async void OnConnectionEvent(object sender, ConnectionEventArgs e)
        {
            if (e.NewState == ConnectionEventArgs.EState.DISCONNECTED)
            {
                await Adb.StopScreenCappingAsync();

                ScreenCapAdjustLayout(false);
            }
        }
Esempio n. 11
0
 public void Update()
 {
     if (_device.State == DeviceState.ONLINE)
     {
         _root    = Adb.ExecuteAdbCommand(Adb.FormAdbShellCommand(_device, false, "su", "-v"));
         _busybox = Adb.ExecuteAdbCommand(Adb.FormAdbShellCommand(_device, false, "busybox"));
         _getprop = Adb.ExecuteAdbCommand(Adb.FormAdbShellCommand(_device, false, "getprop"));
     }
 }
Esempio n. 12
0
        /// <summary>
        /// Calls a phone number on the Android device
        /// </summary>
        /// <param name="phoneNumber">Phone number to call</param>
        public void CallPhoneNumber(string phoneNumber)
        {
            if (this.device.State != DeviceState.ONLINE)
                return;

            AdbCommand adbCmd = Adb.FormAdbShellCommand(this.device, false, "service", "call", "phone", "2", "s16", phoneNumber);
            Adb.ExecuteAdbCommandNoReturn(adbCmd);
            adbCmd = Adb.FormAdbShellCommand(this.device, false, "input", "keyevent", (int)KeyEventCode.BACK);
            Adb.ExecuteAdbCommandNoReturn(adbCmd);
        }
Esempio n. 13
0
        public async Task GetState(string[] output, AdbState state)
        {
            // arrange
            var processManager = new TestProcessManager();

            processManager.AddProcess(output);
            var adb = new Adb(processManager);

            var result = await adb.GetState();

            processManager.Stub.AssertWasCalled(_ => _.CreateProcess(Arg <string> .Is.Anything, Arg <string> .Matches(commands => commands.Contains("get-state"))));
            Assert.IsTrue(result == state);
        }
Esempio n. 14
0
        /// <summary>
        /// Run the process.
        /// </summary>
        protected override void DoWork()
        {
            // Get APK package name
            var apk         = new ApkFile(apkPath);
            var packageName = apk.Manifest.PackageName;

            // Now install
            var adb = new Adb {
                Logger = LogOutput
            };

            adb.InstallApk(device.Serial, apkPath, packageName, Adb.Timeout.InstallApk);
        }
Esempio n. 15
0
        public override int Execute([NotNull] CommandContext context, [NotNull] DeviceInfoCommandSettings settings)
        {
            try
            {
                var adb     = new Adb(settings?.Home);
                var devices = adb.GetDevices();

                var deviceFilterSpecified = settings.Devices?.Any() ?? false;

                var results = new List <DeviceWrapper>();

                foreach (var device in devices)
                {
                    // If filtering on device, check that this is in the list
                    if (deviceFilterSpecified && !settings.Devices.Any(d => IsPropertyMatch(device.Serial, d)))
                    {
                        continue;
                    }

                    var props = adb.GetProperties(device.Serial, settings.Properties);

                    if (settings.Format == OutputFormat.None)
                    {
                        var rule = new Rule(device.Serial);
                        AnsiConsole.Render(rule);

                        OutputHelper.OutputTable(props, new[] { "Property Name", "Property Value" },
                                                 i => new[] { i.Key, i.Value });

                        AnsiConsole.WriteLine();
                    }
                    results.Add(new DeviceWrapper
                    {
                        Device     = device,
                        Properties = adb.GetProperties(device.Serial, settings.Properties)
                    });
                }

                if (settings.Format != OutputFormat.None)
                {
                    OutputHelper.Output(results, settings.Format);
                }
            }
            catch (SdkToolFailedExitException sdkEx)
            {
                Program.WriteException(sdkEx);
                return(1);
            }

            return(0);
        }
Esempio n. 16
0
        /// <summary>
        /// Perform the action.
        /// </summary>
        protected override void DoWork()
        {
            // Listen for devices
            deviceMonitor.Start();
            deviceMonitor.WaitForInitialUpdate();

            // Perform the connect
            connecting = true;
            var adb = new Adb {
                Logger = LogOutput
            };

            adb.Connect(host, port, Adb.Timeout.Connect);
        }
Esempio n. 17
0
        public async Task GetPropertyNull()
        {
            // arrange
            var processManager = new TestProcessManager();

            processManager.AddProcess(new[] { "  " });
            var adb = new Adb(processManager);

            // act
            var result = await adb.SingleDevice.Shell.GetProperty("test.property");

            // assert
            Assert.IsNull(result);
        }
Esempio n. 18
0
 private void buttonRebootRecovery_Click(object sender, EventArgs e)
 {
     if (isConnected())
     {
         cAppend("Rebooting into recovery...");
         Adb.ExecuteAdbCommand(Adb.FormAdbCommand(" reboot recovery"));
         cAppend("Rebooting into recovery... {OK}");
     }
     else
     {
         cAppend("{RebootRecovery} Please connect your device...");
         return;
     }
 }
Esempio n. 19
0
        private static async Task ConfigureForAndroidTests(TestConfiguration config, int?androidSdk, string headBin, CancellationToken cancellationToken)
        {
            // Ensure WebDrivers are installed
            await SdkManager.InstallWebDriver(cancellationToken).ConfigureAwait(false);

            // Ensure latest CmdLine tools are installed
            await SdkManager.InstallLatestCommandLineTools(cancellationToken).ConfigureAwait(false);

            var sdkVersion = ApkHelper.GetAndroidSdkVersion(androidSdk, headBin);

            Logger.WriteLine($"Targeting Android Sdk: {sdkVersion}", LogLevel.Minimal);
            var appActivity = ApkHelper.GetAppActivity(headBin);

            if (!config.Capabilities.ContainsKey("appActivity"))
            {
                config.Capabilities.Add("appActivity", appActivity);
            }

            var emulatorName = $"{AvdManager.DefaultUITestEmulatorName}{sdkVersion}";

            // Check for connected device
            if (await Adb.DeviceIsConnected(cancellationToken))
            {
                var androidDevice = (await Adb.ListDevices(cancellationToken).ConfigureAwait(false)).First();
                config.DeviceName = androidDevice.Name;
                config.UDID       = androidDevice.Id;
                config.OSVersion  = $"{androidDevice.SdkVersion}";
            }
            else
            {
                // Ensure SDK Installed
                await SdkManager.EnsureSdkIsInstalled(sdkVersion, cancellationToken).ConfigureAwait(false);

                // Ensure Emulator Exists
                if (!(await Emulator.ListEmulators(cancellationToken)).Any(x => x == emulatorName))
                {
                    await AvdManager.InstallEmulator(emulatorName, sdkVersion, cancellationToken);
                }

                // Let Appium Start and control the Emulator
                config.DeviceName = emulatorName;
                config.OSVersion  = $"{sdkVersion}";

                if (!config.Capabilities.ContainsKey("avd"))
                {
                    config.Capabilities.Add("avd", emulatorName);
                }
            }
        }
Esempio n. 20
0
        public async Task InstallWithInstaller()
        {
            // arrange
            var processManager = new TestProcessManager();

            processManager.AddProcess(new[] { "Success" });
            var adb = new Adb(processManager);

            // act
            var deviceAdb = adb.SingleDevice;
            await deviceAdb.Install("test.apk", InstallOptions.None, "com.android.vending");

            // assert
            processManager.Stub.AssertWasCalled(_ => _.CreateProcess(Arg <string> .Is.Anything, Arg <string> .Matches(c => c.Contains("-i com.android.vending"))));
        }
Esempio n. 21
0
        public async Task Install(InstallOptions options, string expected)
        {
            // arrange
            var processManager = new TestProcessManager();

            processManager.AddProcess(new[] { "Success" });
            var adb = new Adb(processManager);

            // act
            var deviceAdb = adb.SingleDevice;
            await deviceAdb.Install("test.apk", options);

            // assert
            processManager.Stub.AssertWasCalled(_ => _.CreateProcess(Arg <string> .Is.Anything, Arg <string> .Matches(c => c.Contains(expected))));
        }
Esempio n. 22
0
        public async Task SingleEmulator()
        {
            // arrange
            var processManager = new TestProcessManager();

            processManager.AddProcess(new[] { "Some output" });
            var adb = new Adb(processManager);

            // act
            var deviceAdb = adb.SingleEmulator;
            await deviceAdb.RunCommand("test");

            // assert
            processManager.Stub.AssertWasCalled(_ => _.CreateProcess(Arg <string> .Is.Anything, Arg <string> .Matches(commands => commands.Contains("-e test"))));
        }
Esempio n. 23
0
        public async Task InstallResult(string output, string expected)
        {
            // arrange
            var processManager = new TestProcessManager();

            processManager.AddProcess(new[] { "3584 KB/s (69747 bytes in 0.019s)", "        pkg: /data/local/tmp/LocaleChanger.apk", output });
            var adb = new Adb(processManager);

            // act
            var deviceAdb = adb.SingleDevice;
            var result    = await deviceAdb.Install("test.apk");

            // assert
            Assert.AreEqual(expected, result);
        }
Esempio n. 24
0
        private void bd_Click(object sender, RoutedEventArgs e)
        {
            AndroidController a       = AndroidController.Instance;
            string            c       = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\SGEA\\sgea.db";
            string            imagens = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\SGEA\\Imagens";

            if (File.Exists(c))
            {
                if (a.HasConnectedDevices)
                {
                    c       = "\"" + c + "\"";
                    imagens = "\"" + imagens + "\"";
                    Device d = a.GetConnectedDevice(a.ConnectedDevices[0]);
                    for (int i = 0; i < a.ConnectedDevices.Count; i++)
                    {
                        d = a.GetConnectedDevice(a.ConnectedDevices[i]);
                        if (!d.SerialNumber.Contains("emulator"))
                        {
                            break;
                        }
                    }
                    var ad = Adb.FormAdbShellCommand(d, false, "rmdir -r sdcard/SGEA");
                    Adb.ExecuteAdbCommand(ad);
                    ad = Adb.FormAdbShellCommand(d, false, "mkdir sdcard/SGEA");
                    Adb.ExecuteAdbCommand(ad);
                    ad = Adb.FormAdbShellCommand(d, false, "mkdir sdcard/SGEA/Imagens");
                    Adb.ExecuteAdbCommand(ad);
                    bool b = d.PushFile(c, "sdcard/SGEA", 100000);
                    bool f = d.PushFile(imagens, "sdcard/SGEA/Imagens/", 100000);
                    if (b && f)
                    {
                        Xceed.Wpf.Toolkit.MessageBox.Show("Banco de Dados foi transferido com sucesso");
                    }
                    else
                    {
                        Xceed.Wpf.Toolkit.MessageBox.Show("Banco de Dados não foi transferido");
                    }
                }
                else
                {
                    Xceed.Wpf.Toolkit.MessageBox.Show("Não há um celular Android conectado por USB");
                }
            }
            else
            {
                Xceed.Wpf.Toolkit.MessageBox.Show("O banco de dados não existe. \nPor favor, entre em contato conosco");
            }
        }
Esempio n. 25
0
        public async Task FailPullResult()
        {
            // arrange
            var processManager = new TestProcessManager();

            processManager.AddProcess(new[] { "adb: error: remote object '/mnt/sdcard/Log2.txt' does not exist" });
            var adb = new Adb(processManager);

            // act
            var deviceAdb = adb.SingleDevice;
            var result    = await deviceAdb.Pull("/mnt/sdcard/", "Log.txt");

            // assert
            Assert.IsFalse(result.Success);
            Assert.AreEqual("remote object '/mnt/sdcard/Log2.txt' does not exist", result.Error);
        }
Esempio n. 26
0
        public async Task TargetDevice()
        {
            // arrange
            const string id             = "Device ID";
            var          processManager = new TestProcessManager();

            processManager.AddProcess(new[] { "Some output" });
            var adb = new Adb(processManager);

            // act
            var deviceAdb = adb.Target(id);
            await deviceAdb.RunCommand("test");

            // assert
            processManager.Stub.AssertWasCalled(_ => _.CreateProcess(Arg <string> .Is.Anything, Arg <string> .Matches(commands => commands.Contains(String.Format("-s \"{0}\" test", id)))));
        }
Esempio n. 27
0
        public async Task FailPushResult2()
        {
            // arrange
            var processManager = new TestProcessManager();

            processManager.AddProcess(new[] { "adb: error: failed to copy 'Log.txt' to '/mnt/rtyrtyurt': Read-only file system" });
            var adb = new Adb(processManager);

            // act
            var deviceAdb = adb.SingleDevice;
            var result    = await deviceAdb.Pull("/mnt/rtyrtyurt", "Log.txt");

            // assert
            Assert.IsFalse(result.Success);
            Assert.AreEqual("Read-only file system", result.Error);
        }
Esempio n. 28
0
        public async Task FailPushResult()
        {
            // arrange
            var processManager = new TestProcessManager();

            processManager.AddProcess(new[] { "adb: error: failed to copy 'Log.txt' to '/mnt/sdcard2/Log.txt': Permission denied" });
            var adb = new Adb(processManager);

            // act
            var deviceAdb = adb.SingleDevice;
            var result    = await deviceAdb.Pull("/mnt/sdcard/", "Log.txt");

            // assert
            Assert.IsFalse(result.Success);
            Assert.AreEqual("Permission denied", result.Error);
        }
Esempio n. 29
0
        public async Task SuccessPushResult()
        {
            // arrange
            var processManager = new TestProcessManager();

            processManager.AddProcess(new[] { "[100%] /mnt/sdcard/Log.txt" });
            var adb = new Adb(processManager);

            // act
            var deviceAdb = adb.SingleDevice;
            var result    = await deviceAdb.Push("Log.txt", "/mnt/sdcard/");

            // assert
            Assert.IsTrue(result.Success);
            Assert.IsNull(result.Error);
        }
Esempio n. 30
0
 private async void ScreenCapImage_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
 {
     if (ScreenCapture == Adb && Adb.IsScreenCapActive && !Adb.IsScreenCapOutOfDate && Properties.Settings.Default.ScreenCapEnableTap && Adb.CurrentScreenCap != null)
     {
         Image scImage = sender as Image;
         if (scImage == null)
         {
             return;
         }
         Point point = e.MouseDevice.GetPosition((FrameworkElement)sender);
         point.X  *= Adb.CurrentScreenCap.Width / scImage.ActualWidth;
         point.Y  *= Adb.CurrentScreenCap.Height / scImage.ActualHeight;
         e.Handled = true;
         await Adb.DoTapAsync(point);
     }
 }
Esempio n. 31
0
        private LocalLaunchOptions SetupForDebuggingWorker(CancellationToken token)
        {
            CancellationTokenRegistration onCancelRegistration = token.Register(() =>
            {
                _gdbServerExecCancellationSource.Cancel();
            });

            using (onCancelRegistration)
            {
                // TODO: Adb exception messages should be improved. Example, if ADB is not started, this is returned:
                //    +		[libadb.AdbException]	{"Could not connect to the adb.exe server. See InnerException for details."}	libadb.AdbException
                // 'See InnerException for details.' should not be there. It should just add the inner exception message:
                //    [System.Net.Sockets.SocketException]	{"No connection could be made because the target machine actively refused it 127.0.0.1:5037"}	System.Net.Sockets.SocketException

                Device device = null;
                string workingDirectory = null;
                string gdbServerRemotePath = null;
                string gdbServerSocketDescription = null;
                Task taskGdbServer = null;
                int gdbPortNumber = 0;
                int progressCurrentIndex = 0;
                int progressStepCount = 0;

                List<NamedAction> actions = new List<NamedAction>();

                actions.Add(new NamedAction(LauncherResources.Step_ResolveInstallPaths, () =>
                {
                    _installPaths = InstallPaths.Resolve(token, _launchOptions);
                }));

                actions.Add(new NamedAction(LauncherResources.Step_ConnectToDevice, () =>
                {
                    Adb adb;
                    try
                    {
                        adb = new Adb(_installPaths.SDKRoot);
                    }
                    catch (ArgumentException)
                    {
                        throw new LauncherException(Telemetry.LaunchFailureCode.InvalidAndroidSDK, string.Format(CultureInfo.CurrentCulture, LauncherResources.Error_InvalidAndroidSDK, _installPaths.SDKRoot));
                    }

                    try
                    {
                        adb.Start();
                        device = adb.GetDeviceById(_launchOptions.DeviceId);

                        // There is a rare case, which we have seen it a few times now with the Android emulator where the device will be initially
                        // in the offline state. But after a very short amount of time it comes online. Retry waiting for this.
                        if (device.GetState().HasFlag(DeviceState.Offline))
                        {
                            // Add in an extra progress step and update the dialog
                            progressStepCount++;

                            _waitLoop.SetProgress(progressStepCount, progressCurrentIndex, LauncherResources.Step_WaitingForDeviceToComeOnline);
                            progressCurrentIndex++;

                            const int waitTimePerIteration = 50;
                            const int maxTries = 5000 / waitTimePerIteration; // We will wait for up to 5 seconds

                            // NOTE: libadb has device discovery built in which we could allegedly use instead of a retry loop,
                            // but I couldn't get this to work (though the problem is so rare, I had a lot of trouble testing it), so just using
                            // a retry loop.
                            for (int cTry = 0; true; cTry++)
                            {
                                if (cTry == maxTries)
                                {
                                    throw new LauncherException(Telemetry.LaunchFailureCode.DeviceOffline, LauncherResources.Error_DeviceOffline);
                                }

                                // Sleep for a little while unless this operation is canceled
                                if (token.WaitHandle.WaitOne(waitTimePerIteration))
                                {
                                    throw new OperationCanceledException();
                                }

                                if (!device.GetState().HasFlag(DeviceState.Offline))
                                {
                                    break; // we are no longer offline
                                }
                            }
                        }
                    }
                    catch (AdbException)
                    {
                        throw new LauncherException(Telemetry.LaunchFailureCode.DeviceNotResponding, LauncherResources.Error_DeviceNotResponding);
                    }
                }));

                actions.Add(new NamedAction(LauncherResources.Step_InspectingDevice, () =>
                {
                    try
                    {
                        DeviceAbi deviceAbi = device.Abi;
                        if (deviceAbi == DeviceAbi.unknown)
                            deviceAbi = device.Abi2;

                        switch (_launchOptions.TargetArchitecture)
                        {
                            case TargetArchitecture.ARM:
                                if (deviceAbi != DeviceAbi.armeabi && deviceAbi != DeviceAbi.armeabiv7a)
                                {
                                    throw GetBadDeviceAbiException(deviceAbi);
                                }
                                break;

                            case TargetArchitecture.X86:
                                if (deviceAbi != DeviceAbi.x86)
                                {
                                    throw GetBadDeviceAbiException(deviceAbi);
                                }
                                break;

                            default:
                                Debug.Fail("New target architucture support added without updating this code???");
                                throw new InvalidOperationException();
                        }

                        if (_launchOptions.TargetArchitecture == TargetArchitecture.ARM && device.IsEmulator)
                        {
                            _isUsingArmEmulator = true;
                        }

                        _shell = device.Shell;
                    }
                    catch (AdbException)
                    {
                        throw new LauncherException(Telemetry.LaunchFailureCode.DeviceNotResponding, LauncherResources.Error_DeviceNotResponding);
                    }

                    VerifySdkVersion();

                    string pwdCommand = string.Concat("run-as ", _launchOptions.Package, " /system/bin/sh -c pwd");
                    ExecCommand(pwdCommand);
                    workingDirectory = ParsePwdOutput(_shell.Out);

                    // Kill old processes to make sure we aren't confused and think an old process is still arround
                    gdbServerRemotePath = workingDirectory + "/lib/gdbserver";
                    KillOldInstances(gdbServerRemotePath);

                    string lsCommand = string.Format(CultureInfo.InvariantCulture, "ls {0}", gdbServerRemotePath);
                    string output = ExecCommand(lsCommand);
                    if (string.Compare(output, gdbServerRemotePath, StringComparison.OrdinalIgnoreCase) != 0)
                    {
                        throw new LauncherException(Telemetry.LaunchFailureCode.NoGdbServer, string.Format(CultureInfo.CurrentCulture, LauncherResources.Error_NoGdbServer, gdbServerRemotePath));
                    }
                }));

                if (!_launchOptions.IsAttach)
                {
                    actions.Add(new NamedAction(LauncherResources.Step_StartingApp, () =>
                    {
                        string activateCommand = string.Concat("am start -D -n ", _launchOptions.Package, "/", _launchOptions.LaunchActivity);
                        ExecCommand(activateCommand);
                        ValidateActivityManagerOutput(activateCommand, _shell.Out);
                    }));
                }

                actions.Add(new NamedAction(LauncherResources.Step_GettingAppProcessId, () =>
                {
                    _appProcessId = GetAppProcessId();
                }));

                actions.Add(new NamedAction(LauncherResources.Step_StartGDBServer, () =>
                {
                    // We will default to using a unix socket with gdbserver as this is what the ndk-gdb script uses. Though we have seen
                    // some machines where this doesn't work and we fall back to TCP instead.
                    const bool useUnixSocket = true;

                    taskGdbServer = StartGdbServer(gdbServerRemotePath, workingDirectory, useUnixSocket, out gdbServerSocketDescription);
                }));

                actions.Add(new NamedAction(LauncherResources.Step_PortForwarding, () =>
                {
                    // TODO: Use a dynamic socket
                    gdbPortNumber = 5039;
                    _jdbPortNumber = 65534;

                    device.Forward(string.Format(CultureInfo.InvariantCulture, "tcp:{0}", gdbPortNumber), gdbServerSocketDescription);
                    if (!_launchOptions.IsAttach)
                    {
                        device.Forward(string.Format(CultureInfo.InvariantCulture, "tcp:{0}", _jdbPortNumber), string.Format(CultureInfo.InvariantCulture, "jdwp:{0}", _appProcessId));
                    }
                }));

                actions.Add(new NamedAction(LauncherResources.Step_DownloadingFiles, () =>
                {
                    //pull binaries from the emulator/device
                    var fileSystem = device.FileSystem;

                    fileSystem.Download(@"/system/bin/app_process", Path.Combine(_launchOptions.IntermediateDirectory, "app_process"), true);
                    fileSystem.Download(@"/system/bin/linker", Path.Combine(_launchOptions.IntermediateDirectory, "linker"), true);
                    fileSystem.Download(@"/system/lib/libc.so", Path.Combine(_launchOptions.IntermediateDirectory, "libc.so"), true);
                }));

                progressStepCount = actions.Count;

                foreach (NamedAction namedAction in actions)
                {
                    token.ThrowIfCancellationRequested();

                    _waitLoop.SetProgress(progressStepCount, progressCurrentIndex, namedAction.Name);
                    progressCurrentIndex++;
                    namedAction.Action();
                }

                _waitLoop.SetProgress(progressStepCount, progressStepCount, string.Empty);

                if (taskGdbServer.IsCompleted)
                {
                    token.ThrowIfCancellationRequested();
                    throw new LauncherException(Telemetry.LaunchFailureCode.GDBServerFailed, LauncherResources.Error_GDBServerFailed);
                }

                if (_launchOptions.LogcatServiceId != Guid.Empty)
                {
                    _eventCallback.OnCustomDebugEvent(_launchOptions.LogcatServiceId, new Guid(LogcatServiceMessage_SourceId), LogcatServiceMessage_NewProcess, _appProcessId, null);
                }

                var launchOptions = new LocalLaunchOptions(_installPaths.GDBPath, string.Format(CultureInfo.InvariantCulture, ":{0}", gdbPortNumber));
                launchOptions.AdditionalSOLibSearchPath = _launchOptions.AdditionalSOLibSearchPath;
                launchOptions.TargetArchitecture = _launchOptions.TargetArchitecture;
                launchOptions.WorkingDirectory = _launchOptions.IntermediateDirectory;
                launchOptions.ExePath = Path.Combine(_launchOptions.IntermediateDirectory, "app_process");
                launchOptions.DebuggerMIMode = MIMode.Gdb;
                launchOptions.VisualizerFile = "Microsoft.Android.natvis";

                return launchOptions;
            }
        }
Esempio n. 32
0
        private LaunchOptions SetupForDebuggingWorker(CancellationToken token)
        {
            CancellationTokenRegistration onCancelRegistration = token.Register(() =>
            {
                _gdbServerExecCancellationSource.Cancel();
            });

            using (onCancelRegistration)
            {
                // TODO: Adb exception messages should be improved. Example, if ADB is not started, this is returned:
                //    +		[libadb.AdbException]	{"Could not connect to the adb.exe server. See InnerException for details."}	libadb.AdbException
                // 'See InnerException for details.' should not be there. It should just add the inner exception message:
                //    [System.Net.Sockets.SocketException]	{"No connection could be made because the target machine actively refused it 127.0.0.1:5037"}	System.Net.Sockets.SocketException

                Device device = null;
                string workingDirectory = null;
                string gdbServerRemotePath = null;
                string gdbServerSocketDescription = null;
                string exePath = null;
                Task taskGdbServer = null;
                int gdbPortNumber = 0;
                int progressCurrentIndex = 0;
                int progressStepCount = 0;

                List<NamedAction> actions = new List<NamedAction>();

                actions.Add(new NamedAction(LauncherResources.Step_ResolveInstallPaths, () =>
                {
                    _installPaths = InstallPaths.Resolve(token, _launchOptions, Logger);
                }));

                actions.Add(new NamedAction(LauncherResources.Step_ConnectToDevice, () =>
                {
                    Adb adb;
                    try
                    {
                        adb = new Adb(_installPaths.SDKRoot);
                    }
                    catch (ArgumentException)
                    {
                        throw new LauncherException(Telemetry.LaunchFailureCode.InvalidAndroidSDK, string.Format(CultureInfo.CurrentCulture, LauncherResources.Error_InvalidAndroidSDK, _installPaths.SDKRoot));
                    }

                    try
                    {
                        adb.Start();
                        device = adb.GetDeviceById(_launchOptions.DeviceId);

                        // There is a rare case, which we have seen it a few times now with the Android emulator where the device will be initially
                        // in the offline state. But after a very short amount of time it comes online. Retry waiting for this.
                        if (device.GetState().HasFlag(DeviceState.Offline))
                        {
                            // Add in an extra progress step and update the dialog
                            progressStepCount++;

                            _waitLoop.SetProgress(progressStepCount, progressCurrentIndex, LauncherResources.Step_WaitingForDeviceToComeOnline);
                            progressCurrentIndex++;

                            const int waitTimePerIteration = 50;
                            const int maxTries = 5000 / waitTimePerIteration; // We will wait for up to 5 seconds

                            // NOTE: libadb has device discovery built in which we could allegedly use instead of a retry loop,
                            // but I couldn't get this to work (though the problem is so rare, I had a lot of trouble testing it), so just using
                            // a retry loop.
                            for (int cTry = 0; true; cTry++)
                            {
                                if (cTry == maxTries)
                                {
                                    throw new LauncherException(Telemetry.LaunchFailureCode.DeviceOffline, LauncherResources.Error_DeviceOffline);
                                }

                                // Sleep for a little while unless this operation is canceled
                                if (token.WaitHandle.WaitOne(waitTimePerIteration))
                                {
                                    throw new OperationCanceledException();
                                }

                                if (!device.GetState().HasFlag(DeviceState.Offline))
                                {
                                    break; // we are no longer offline
                                }
                            }
                        }
                    }
                    catch (AdbException)
                    {
                        throw new LauncherException(Telemetry.LaunchFailureCode.DeviceNotResponding, LauncherResources.Error_DeviceNotResponding);
                    }
                }));

                actions.Add(new NamedAction(LauncherResources.Step_InspectingDevice, () =>
                {
                    try
                    {
                        DeviceAbi[] allowedAbis;
                        switch (_launchOptions.TargetArchitecture)
                        {
                            case TargetArchitecture.ARM:
                                allowedAbis = new DeviceAbi[] { DeviceAbi.armeabi, DeviceAbi.armeabiv7a };
                                break;

                            case TargetArchitecture.ARM64:
                                allowedAbis = new DeviceAbi[] { DeviceAbi.arm64v8a };
                                break;

                            case TargetArchitecture.X86:
                                allowedAbis = new DeviceAbi[] { DeviceAbi.x86 };
                                break;

                            case TargetArchitecture.X64:
                                allowedAbis = new DeviceAbi[] { DeviceAbi.x64 };
                                break;

                            default:
                                Debug.Fail("New target architucture support added without updating this code???");
                                throw new InvalidOperationException();
                        }

                        if (!DoesDeviceSupportAnyAbi(device, allowedAbis))
                        {
                            throw GetBadDeviceAbiException(device.Abi);
                        }

                        if (_launchOptions.TargetArchitecture == TargetArchitecture.ARM && device.IsEmulator)
                        {
                            _isUsingArmEmulator = true;
                        }

                        _shell = device.Shell;
                    }
                    catch (AdbException)
                    {
                        throw new LauncherException(Telemetry.LaunchFailureCode.DeviceNotResponding, LauncherResources.Error_DeviceNotResponding);
                    }

                    VerifySdkVersion();

                    if (_targetEngine == TargetEngine.Native)
                    {
                        string pwdCommand = string.Concat("run-as ", _launchOptions.Package, " /system/bin/sh -c pwd");
                        ExecCommand(pwdCommand);
                        workingDirectory = PwdOutputParser.ExtractWorkingDirectory(_shell.Out, _launchOptions.Package);
                        gdbServerRemotePath = GetGdbServerPath(workingDirectory, device);

                        KillOldInstances(gdbServerRemotePath);
                    }
                }));

                if (!_launchOptions.IsAttach)
                {
                    actions.Add(new NamedAction(LauncherResources.Step_StartingApp, () =>
                    {
                        string activateCommand = string.Concat("am start -D -n ", _launchOptions.Package, "/", _launchOptions.LaunchActivity);
                        ExecCommand(activateCommand);
                        ValidateActivityManagerOutput(activateCommand, _shell.Out);
                    }));
                }

                actions.Add(new NamedAction(LauncherResources.Step_GettingAppProcessId, () =>
                {
                    _appProcessId = GetAppProcessId();
                }));

                if (_targetEngine == TargetEngine.Native)
                {
                    actions.Add(new NamedAction(LauncherResources.Step_StartGDBServer, () =>
                    {
                        // We will default to using a unix socket with gdbserver as this is what the ndk-gdb script uses. Though we have seen
                        // some machines where this doesn't work and we fall back to TCP instead.
                        const bool useUnixSocket = true;

                        taskGdbServer = StartGdbServer(gdbServerRemotePath, workingDirectory, useUnixSocket, out gdbServerSocketDescription);
                    }));
                }

                actions.Add(new NamedAction(LauncherResources.Step_PortForwarding, () =>
                {
                    // TODO: Use a dynamic socket
                    gdbPortNumber = 5039;
                    _jdbPortNumber = 65534;

                    if (_targetEngine == TargetEngine.Native)
                    {
                        device.Forward(string.Format(CultureInfo.InvariantCulture, "tcp:{0}", gdbPortNumber), gdbServerSocketDescription);
                    }

                    device.Forward(string.Format(CultureInfo.InvariantCulture, "tcp:{0}", _jdbPortNumber), string.Format(CultureInfo.InvariantCulture, "jdwp:{0}", _appProcessId));
                }));

                if (_targetEngine == TargetEngine.Native)
                {
                    actions.Add(new NamedAction(LauncherResources.Step_DownloadingFiles, () =>
                    {
                        //pull binaries from the emulator/device
                        var fileSystem = device.FileSystem;

                        string app_process_suffix = String.Empty;
                        switch (_launchOptions.TargetArchitecture)
                        {
                            case TargetArchitecture.X86:
                            case TargetArchitecture.ARM:
                                app_process_suffix = "32";
                                break;
                            case TargetArchitecture.X64:
                            case TargetArchitecture.ARM64:
                                app_process_suffix = "64";
                                break;
                            default:
                                Debug.Fail("Unsupported Target Architecture!");
                                break;
                        }

                        string app_process = String.Concat("app_process", app_process_suffix);
                        exePath = Path.Combine(_launchOptions.IntermediateDirectory, app_process);

                        bool retry = false;
                        try
                        {
                            fileSystem.Download(@"/system/bin/" + app_process, exePath, true);
                        }
                        catch (AdbException) when (String.Compare(app_process_suffix, "32", StringComparison.OrdinalIgnoreCase) == 0)
                        {
                            // Older devices don't have an 'app_process32', only an 'app_process', so retry
                            // NOTE: libadb doesn't have an error code property to verify that this is caused
                            // by the file not being found.
                            retry = true;
                        }

                        if (retry)
                        {
                            app_process = "app_process";
                            exePath = Path.Combine(_launchOptions.IntermediateDirectory, app_process);
                            fileSystem.Download(@"/system/bin/app_process", exePath, true);
                        }

                        //on 64 bit, 'linker64' is the 64bit version and 'linker' is the 32 bit version
                        string suffix64bit = String.Empty;
                        if (_launchOptions.TargetArchitecture == TargetArchitecture.X64 || _launchOptions.TargetArchitecture == TargetArchitecture.ARM64)
                        {
                            suffix64bit = "64";
                        }

                        string linker = String.Concat("linker", suffix64bit);
                        fileSystem.Download(String.Concat(@"/system/bin/", linker), Path.Combine(_launchOptions.IntermediateDirectory, linker), true);

                        //on 64 bit, libc.so lives in /system/lib64/, on 32 bit it lives in simply /system/lib/
                        fileSystem.Download(@"/system/lib" + suffix64bit + "/libc.so", Path.Combine(_launchOptions.IntermediateDirectory, "libc.so"), true);
                    }));
                }

                progressStepCount = actions.Count;

                foreach (NamedAction namedAction in actions)
                {
                    token.ThrowIfCancellationRequested();

                    _waitLoop.SetProgress(progressStepCount, progressCurrentIndex, namedAction.Name);
                    progressCurrentIndex++;
                    namedAction.Action();
                }

                _waitLoop.SetProgress(progressStepCount, progressStepCount, string.Empty);

                if (_targetEngine == TargetEngine.Native && taskGdbServer.IsCompleted)
                {
                    token.ThrowIfCancellationRequested();
                    throw new LauncherException(Telemetry.LaunchFailureCode.GDBServerFailed, LauncherResources.Error_GDBServerFailed);
                }

                if (_launchOptions.LogcatServiceId != Guid.Empty)
                {
                    _eventCallback.OnCustomDebugEvent(_launchOptions.LogcatServiceId, new Guid(LogcatServiceMessage_SourceId), LogcatServiceMessage_NewProcess, _appProcessId, null);
                }

                LaunchOptions launchOptions = null;
                if (_targetEngine == TargetEngine.Native)
                {
                    launchOptions = new LocalLaunchOptions(_installPaths.GDBPath, string.Format(CultureInfo.InvariantCulture, ":{0}", gdbPortNumber), 0, null);
                    launchOptions.ExePath = exePath;
                }
                else
                {
                    launchOptions = new JavaLaunchOptions(_launchOptions.JVMHost, _launchOptions.JVMPort, _launchOptions.SourceRoots, _launchOptions.Package);
                }

                launchOptions.AdditionalSOLibSearchPath = _launchOptions.AdditionalSOLibSearchPath;
                launchOptions.AbsolutePrefixSOLibSearchPath = _launchOptions.AbsolutePrefixSOLibSearchPath;

                // The default ABI is 'Cygwin' in the Android NDK >= r11 for Windows.
                launchOptions.SetupCommands = new ReadOnlyCollection<LaunchCommand>( new LaunchCommand[]
                {
                    new LaunchCommand("-gdb-set osabi GNU/Linux")
                });

                launchOptions.TargetArchitecture = _launchOptions.TargetArchitecture;
                launchOptions.WorkingDirectory = _launchOptions.IntermediateDirectory;

                launchOptions.DebuggerMIMode = MIMode.Gdb;

                launchOptions.VisualizerFile = "Microsoft.Android.natvis";
                launchOptions.WaitDynamicLibLoad = _launchOptions.WaitDynamicLibLoad;

                return launchOptions;
            }
        }