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

        public async Task <int> OnDebuggerLogcatEvent(IDebugEngine2 pEngine, IDebugProcess2 pProcess, IDebugProgram2 pProgram, IDebugThread2 pThread, IDebugEvent2 pEvent, Guid riidEvent, uint dwAttrib)
        {
            LoggingUtils.PrintFunction();

            try
            {
                DebugEngineEvent.DebuggerLogcatEvent debuggerLogcatEvent = pEvent as DebugEngineEvent.DebuggerLogcatEvent;

                using (SyncRedirectProcess command = AndroidAdb.AdbCommand(debuggerLogcatEvent.HostDevice, "logcat", "-c"))
                {
                    command.StartAndWaitForExit();
                }

                m_adbLogcatProcess = AndroidAdb.AdbCommandAsync(debuggerLogcatEvent.HostDevice, "logcat", "");

                m_adbLogcatListener = new DeviceLogcatListener();

                m_adbLogcatProcess.Start(m_adbLogcatListener);

                return(VSConstants.S_OK);
            }
            catch (Exception e)
            {
                LoggingUtils.HandleException(e);

                return(VSConstants.E_FAIL);
            }
        }
Esempio n. 2
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public int OnDebuggerLogcatEvent(IDebugEngine2 pEngine, IDebugProcess2 pProcess, IDebugProgram2 pProgram, IDebugThread2 pThread, IDebugEvent2 pEvent, ref Guid riidEvent, uint dwAttrib)
        {
            LoggingUtils.PrintFunction();

            try
            {
                DebugEngineEvent.DebuggerLogcatEvent debuggerLogcatEvent = pEvent as DebugEngineEvent.DebuggerLogcatEvent;

                using (SyncRedirectProcess command = AndroidAdb.AdbCommand(debuggerLogcatEvent.HostDevice, "logcat", "-c"))
                {
                    command.StartAndWaitForExit();
                }

                m_adbLogcatProcess = AndroidAdb.AdbCommandAsync(debuggerLogcatEvent.HostDevice, "logcat", "");

                m_adbLogcatListener = new DeviceLogcatListener();

                if (m_adbLogcatProcess == null)
                {
                    throw new InvalidOperationException("Failed to launch logcat application.");
                }

                if (m_adbLogcatListener == null)
                {
                    throw new InvalidOperationException("Failed to launch logcat listener.");
                }

                m_adbLogcatProcess.Start(m_adbLogcatListener);

                return(VSConstants.S_OK);
            }
            catch (Exception e)
            {
                LoggingUtils.HandleException(e);

                return(VSConstants.E_FAIL);
            }
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public LaunchConfiguration GetLaunchConfigurationFromProjectProperties(IDictionary <string, string> projectProperties)
        {
            LoggingUtils.PrintFunction();

            //
            // Retrieve standard project macro values, and determine the preferred debugger configuration.
            //

            string projectTargetName = EvaluateProjectProperty(projectProperties, "ConfigurationGeneral", "TargetName");

            string projectProjectDir = EvaluateProjectProperty(projectProperties, "ConfigurationGeneral", "ProjectDir");

            string debuggerMode = EvaluateProjectProperty(projectProperties, "AndroidPlusPlusDebugger", "DebuggerConfigMode");

            string debuggerTargetApk = EvaluateProjectProperty(projectProperties, "AndroidPlusPlusDebugger", "DebuggerConfigTargetApk");

            string debuggerUpToDateCheck = EvaluateProjectProperty(projectProperties, "AndroidPlusPlusDebugger", "DebuggerConfigUpToDateCheck");

            string debuggerLaunchActivity = EvaluateProjectProperty(projectProperties, "AndroidPlusPlusDebugger", "DebuggerConfigLaunchActivity");

            string debuggerDebugMode = EvaluateProjectProperty(projectProperties, "AndroidPlusPlusDebugger", "DebuggerConfigDebugMode");

            string debuggerOpenGlTrace = EvaluateProjectProperty(projectProperties, "AndroidPlusPlusDebugger", "DebuggerConfigOpenGlTrace");

            string debuggerKeepAppData = EvaluateProjectProperty(projectProperties, "AndroidPlusPlusDebugger", "DebuggerConfigKeepAppData");

            string debuggerInstallerPackage = EvaluateProjectProperty(projectProperties, "AndroidPlusPlusDebugger", "DebuggerConfigInstallerPackage");

            if (string.IsNullOrEmpty(debuggerMode))
            {
                debuggerMode = "Custom";
            }
            else if (debuggerMode.Equals("vs-android"))
            {
                //
                // Support for vs-android.
                //

                string antBuildPath = EvaluateProjectProperty(projectProperties, "AntBuild", "AntBuildPath");

                string antBuildType = EvaluateProjectProperty(projectProperties, "AntBuild", "AntBuildType");

                string antBuildXml = Path.Combine(antBuildPath, "build.xml");

                XmlDocument buildXmlDocument = new XmlDocument();

                buildXmlDocument.Load(antBuildXml);

                string antBuildXmlProjectName = buildXmlDocument.DocumentElement.GetAttribute("name");

                debuggerTargetApk = Path.Combine(antBuildPath, "bin", string.Format(CultureInfo.InvariantCulture, "{0}-{1}.apk", antBuildXmlProjectName, antBuildType));
            }

            //
            // Ensure the provided target APK is found and absolute.
            //

            if (string.IsNullOrEmpty(debuggerTargetApk))
            {
                throw new FileNotFoundException("Could not locate target application. Empty path provided.");
            }
            else if (!Path.IsPathRooted(debuggerTargetApk) && !string.IsNullOrWhiteSpace(projectProjectDir))
            {
                debuggerTargetApk = Path.Combine(projectProjectDir, debuggerTargetApk);
            }

            if (!Path.IsPathRooted(debuggerTargetApk))
            {
                throw new InvalidOperationException("Could not evaluate an absolute path to the target application. Tried: " + debuggerTargetApk);
            }

            debuggerTargetApk = Path.GetFullPath(debuggerTargetApk); // normalises relative paths.

            if (!File.Exists(debuggerTargetApk))
            {
                throw new FileNotFoundException("Could not find required target application. Expected: " + debuggerTargetApk);
            }

            //
            // Find the selected Android SDK (and associated build-tools) deployment.
            //

            string androidSdkRoot = EvaluateProjectProperty(projectProperties, "ConfigurationGeneral", "AndroidSdkRoot");

            if (string.IsNullOrWhiteSpace(androidSdkRoot))
            {
                throw new DirectoryNotFoundException("Could not locate Android SDK. \"AndroidSdkRoot\" property is empty.");
            }
            else if (!Directory.Exists(androidSdkRoot))
            {
                throw new DirectoryNotFoundException("Could not locate Android SDK. \"AndroidSdkRoot\" property references a directory which does not exist. Expected: " + androidSdkRoot);
            }

            string androidSdkBuildToolsVersion = EvaluateProjectProperty(projectProperties, "ConfigurationGeneral", "AndroidSdkBuildToolsVersion");

            string androidSdkBuildToolsPath = Path.Combine(androidSdkRoot, "build-tools", androidSdkBuildToolsVersion);

            if (!Directory.Exists(androidSdkBuildToolsPath))
            {
                throw new DirectoryNotFoundException(string.Format(CultureInfo.CurrentCulture, "Could not locate Android SDK build-tools (v{0}). Expected: {1}", androidSdkBuildToolsVersion, androidSdkBuildToolsPath));
            }

            //
            // Spawn a AAPT.exe instance to gain some extra information about the APK we are trying to load.
            //

            string applicationPackageName = string.Empty;

            string applicationLaunchActivity = string.Empty;

            string aaptToolPath = Path.Combine(androidSdkBuildToolsPath, "aapt.exe");

            if (!File.Exists(aaptToolPath))
            {
                throw new FileNotFoundException("Could not locate AAPT tool (under Android SDK build-tools).", aaptToolPath);
            }

            using (SyncRedirectProcess getApkDetails = new SyncRedirectProcess(aaptToolPath, "dump --values badging " + PathUtils.SantiseWindowsPath(debuggerTargetApk)))
            {
                int exitCode = getApkDetails.StartAndWaitForExit();

                if (exitCode != 0)
                {
                    throw new InvalidOperationException("AAPT failed to dump required application badging information. Exit-code: " + exitCode);
                }

                var apkDetails = getApkDetails.StandardOutput.Replace("\r", "").Split(new char [] { '\n' });

                foreach (string singleLine in apkDetails)
                {
                    if (singleLine.StartsWith("package: ", StringComparison.OrdinalIgnoreCase))
                    {
                        //
                        // Retrieve package name from format: "package: name='com.example.hellogdbserver' versionCode='1' versionName='1.0'"
                        //

                        var packageData = singleLine.Substring("package: ".Length).Split(' ');

                        foreach (string data in packageData)
                        {
                            if (data.StartsWith("name=", StringComparison.OrdinalIgnoreCase))
                            {
                                applicationPackageName = data.Substring("name=".Length).Trim('\'');
                            }
                        }
                    }
                    else if (singleLine.StartsWith("launchable-activity: ", StringComparison.OrdinalIgnoreCase))
                    {
                        var launchActivityData = singleLine.Substring("launchable-activity: ".Length).Split(' ');

                        foreach (string data in launchActivityData)
                        {
                            if (data.StartsWith("name=", StringComparison.OrdinalIgnoreCase))
                            {
                                applicationLaunchActivity = data.Substring("name=".Length).Trim('\'');
                            }
                        }
                    }
                }
            }

            //
            // If a specific launch activity was not requested, ensure that the default one is referenced.
            //

            if (string.IsNullOrEmpty(debuggerLaunchActivity))
            {
                debuggerLaunchActivity = applicationLaunchActivity;
            }

            LaunchConfiguration launchConfig = new LaunchConfiguration
            {
                ["TargetApk"] = debuggerTargetApk,

                ["UpToDateCheck"] = debuggerUpToDateCheck,

                ["PackageName"] = applicationPackageName,

                ["LaunchActivity"] = debuggerLaunchActivity,

                ["DebugMode"] = debuggerDebugMode,

                ["OpenGlTrace"] = debuggerOpenGlTrace,

                ["KeepAppData"] = debuggerKeepAppData,

                ["InstallerPackage"] = debuggerInstallerPackage
            };

            return(launchConfig);
        }