//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 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; } }