private void InitFilterRegex(string filter) { if (string.IsNullOrEmpty(filter)) { return; } if (m_Device.SupportsFilteringByRegex) { // When doing searching by filter, we use --regex command. // Note: there's no command line argument to disable or enable regular expressions for logcat // Thus when we want to disable regular expressions, we simply provide filter with escaped characters to --regex command this.m_Filter = m_FilterIsRegex ? filter : Regex.Escape(filter); return; } if (!this.m_FilterIsRegex) { this.m_Filter = filter; return; } try { this.m_Filter = filter; m_ManualFilterRegex = new Regex(m_Filter, RegexOptions.Compiled); } catch (Exception ex) { var error = string.Format("Input search filter '{0}' is not a valid regular expression.", Regex.Escape(m_Filter)); AndroidLogcatInternalLog.Log(error); throw new ArgumentException(error, ex); } }
public static int ParsePidInfo(string packageName, string commandOutput) { string line = null; // Note: Regex is very slow, looping through string is much faster using (var sr = new StringReader(commandOutput)) { while ((line = sr.ReadLine()) != null) { if (line.EndsWith(packageName)) { break; } } } if (string.IsNullOrEmpty(line)) { AndroidLogcatInternalLog.Log("Cannot get process status for '{0}'.", packageName); return(-1); } var regex = new Regex(@"\b\d+"); Match match = regex.Match(line); if (!match.Success) { AndroidLogcatInternalLog.Log("Failed to parse pid of '{0}'from '{1}'.", packageName, line); return(-1); } return(int.Parse(match.Groups[0].Value)); }
internal static IAndroidLogcatTaskResult Execute(IAndroidLogcatTaskInput input) { var adb = ((AndroidLogcatRetrieveDeviceIdsInput)input).adb; if (adb == null) { throw new NullReferenceException("ADB interface has to be valid"); } var result = new AndroidLogcatRetrieveDeviceIdsResult(); AndroidLogcatInternalLog.Log("{0} devices", adb.GetADBPath()); var adbOutput = adb.Run(new[] { "devices" }, "Unable to list connected devices. "); foreach (var line in adbOutput.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries).Select(line => line.Trim())) { AndroidLogcatInternalLog.Log(" " + line); if (line.EndsWith("device")) { var deviceId = line.Split(new[] { '\t', ' ' })[0]; result.deviceIds.Add(deviceId); } } return(result); }
private void WorkerThread(object o) { AndroidLogcatInternalLog.Log("Worker thread started"); Profiler.BeginThreadProfiling("AndroidLogcat", "Dispatcher"); while (m_AutoResetEvent.WaitOne() && m_Running) { //Debug.Log("Executing"); AsyncTask task = null; lock (m_AsyncTaskQueue) { if (m_AsyncTaskQueue.Count > 0) { task = m_AsyncTaskQueue.Dequeue(); } } if (task != null && task.asyncAction != null) { m_Sampler.Begin(); var result = task.asyncAction.Invoke(task.taskData); m_Sampler.End(); lock (m_IntegrateTaskQueue) { m_IntegrateTaskQueue.Enqueue(new IntegrationTask() { integrateAction = task.integrateAction, result = result }); } } } AndroidLogcatInternalLog.Log("Worker thread exited"); Profiler.EndThreadProfiling(); m_FinishedEvent.Set(); }
internal void Schedule(IAndroidLogcatTaskInput taskData, Func <IAndroidLogcatTaskInput, IAndroidLogcatTaskResult> asyncAction, Action <IAndroidLogcatTaskResult> integrateAction, bool synchronous) { if (!m_Running) { AndroidLogcatInternalLog.Log("Ignore schedule action, because dispatcher is not running."); return; } if (synchronous) { integrateAction(asyncAction.Invoke(taskData)); return; } lock (m_AsyncTaskQueue) { var task = new AsyncTask() { taskData = taskData, asyncAction = asyncAction, integrateAction = integrateAction }; m_AsyncTaskQueue.Enqueue(task); if (!m_AutoResetEvent.Set()) { throw new Exception("Failed to signal auto reset event in dispatcher."); } } }
private LogEntry ParseLogEntry(Match m) { DateTime dateTime; var dateValue = m.Groups["date"].Value; if (LogPrintFormat == kThreadTime) { dateValue = "1999-" + dateValue; } try { dateTime = DateTime.Parse(dateValue); } catch (Exception ex) { dateTime = new DateTime(); AndroidLogcatInternalLog.Log("Failed to parse date: " + dateValue + "\n" + ex.Message); } var entry = new LogEntry( dateTime, Int32.Parse(m.Groups["pid"].Value), Int32.Parse(m.Groups["tid"].Value), PriorityStringToEnum(m.Groups["priority"].Value), m.Groups["tag"].Value, m.Groups["msg"].Value); return(entry); }
private static IAndroidLogcatTaskResult QueryMemoryAsync(IAndroidLogcatTaskInput input) { var workInput = ((AndroidLogcatQueryMemoryInput)input); var adb = workInput.adb; if (adb == null) { throw new NullReferenceException("ADB interface has to be valid"); } var cmd = "-s " + workInput.deviceId + " shell dumpsys meminfo " + workInput.packageName; AndroidLogcatInternalLog.Log("{0} {1}", adb.GetADBPath(), cmd); string outputMsg = string.Empty; try { outputMsg = adb.Run(new[] { cmd }, "Failed to query memory for " + workInput.packageName); } catch (Exception ex) { AndroidLogcatInternalLog.Log("Failed to query memory: \n" + ex.Message); } var result = new AndroidLogcatQueryMemoryResult(); result.deviceId = workInput.deviceId; result.packageName = workInput.packageName; result.packageProcessId = workInput.packageProcessId; result.contents = outputMsg; //AndroidLogcatInternalLog.Log(outputMsg); return(result); }
private static IAndroidLogcatTaskResult QueryDevicesAsync(IAndroidLogcatTaskInput input) { var adb = ((AndroidLogcatRetrieveDeviceIdsInput)input).adb; if (adb == null) throw new NullReferenceException("ADB interface has to be valid"); var result = new AndroidLogcatRetrieveDeviceIdsResult(); result.notifyListeners = ((AndroidLogcatRetrieveDeviceIdsInput)input).notifyListeners; AndroidLogcatInternalLog.Log("{0} devices", adb.GetADBPath()); try { var adbOutput = adb.Run(new[] { "devices" }, "Unable to list connected devices. "); foreach (var line in adbOutput.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries).Select(line => line.Trim())) { AndroidLogcatInternalLog.Log(" " + line); AndroidLogcatRetrieveDeviceIdsResult.DeviceInfo info; if (ParseDeviceInfo(line, out info.id, out info.state)) result.deviceInfo.Add(info); } } catch (Exception ex) { AndroidLogcatInternalLog.Log(ex.Message); result.deviceInfo = new List<AndroidLogcatRetrieveDeviceIdsResult.DeviceInfo>(); } return result; }
private void UpdateDebuggablePackages() { // When running test Tools don't exist if (m_Runtime.Tools == null) { return; } var startTime = DateTime.Now; var packagePIDCache = new Dictionary <string, int>(); CheckIfPackagesExited(packagePIDCache); int topActivityPid = 0; string topActivityPackageName = string.Empty; bool checkProjectPackage = true; var selectedDevice = m_Runtime.DeviceQuery.SelectedDevice; if (AndroidLogcatUtilities.GetTopActivityInfo(m_Runtime.Tools.ADB, selectedDevice, ref topActivityPackageName, ref topActivityPid) && topActivityPid > 0) { m_Runtime.UserSettings.CreatePackageInformation(topActivityPackageName, topActivityPid, selectedDevice); checkProjectPackage = topActivityPackageName != PlayerSettings.applicationIdentifier; } if (checkProjectPackage) { int projectApplicationPid = GetPidFromPackageName(packagePIDCache, PlayerSettings.applicationIdentifier, selectedDevice); m_Runtime.UserSettings.CreatePackageInformation(PlayerSettings.applicationIdentifier, projectApplicationPid, selectedDevice); } m_Runtime.UserSettings.CleanupDeadPackagesForDevice(m_Runtime.DeviceQuery.SelectedDevice); AndroidLogcatInternalLog.Log("UpdateDebuggablePackages finished in " + (DateTime.Now - startTime).Milliseconds + " ms"); }
private void OnEnable() { AndroidLogcatInternalLog.Log("OnEnable"); if (m_SearchField == null) { m_SearchField = new SearchField(); } if (m_TagControl == null) { m_TagControl = new AndroidLogcatTagsControl(); } m_TagControl.TagSelectionChanged += TagSelectionChanged; m_SelectedDeviceIndex = -1; m_SelectedDeviceId = null; m_TimeOfLastAutoConnectStart = DateTime.Now; EditorApplication.update += Update; m_FinishedAutoselectingPackage = false; AndroidLogcatInternalLog.Log("Package: {0}, Auto select: {1}", PlayerSettings.applicationIdentifier, AutoSelectPackage); m_StatusBar = new AndroidLogcatStatusBar(); }
internal void OnDisable() { if (!AndroidBridge.AndroidExtensionsInstalled) { return; } if (m_Runtime == null) { AndroidLogcatInternalLog.Log("Runtime was already destroyed."); return; } m_Runtime.UserSettings.Tags.TagSelectionChanged -= TagSelectionChanged; m_Runtime.Closing -= OnDisable; m_Runtime.DeviceQuery.DeviceSelected -= OnSelectedDevice; if (m_Runtime.Settings != null) { m_Runtime.Settings.OnSettingsChanged -= OnSettingsChanged; } StopLogCat(); m_Runtime.Update -= OnUpdate; AndroidLogcatInternalLog.Log("OnDisable, Auto select: {0}", m_AutoSelectPackage); m_Runtime = null; }
internal void SelectDevice(IAndroidLogcatDevice device, bool notifyListeners = true) { if (m_SelectedDevice == device) return; if (device != null && device.State != IAndroidLogcatDevice.DeviceState.Connected) { AndroidLogcatInternalLog.Log("Trying to select device which is not connected: " + device.Id); if (m_SelectedDevice == null) return; m_SelectedDevice = null; } else { m_SelectedDevice = device; } if (m_SelectedDevice != null && !m_Devices.Keys.Contains(m_SelectedDevice.Id)) throw new Exception("Selected device is not among our listed devices"); m_Runtime.UserSettings.LastSelectedDeviceId = m_SelectedDevice != null ? m_SelectedDevice.Id : ""; if (notifyListeners) DeviceSelected?.Invoke(m_SelectedDevice); }
public static Version ParseVersion(string versionString) { #if NET_2_0 return(ParseVersionLegacy(versionString)); #else var vals = versionString.Split('.'); // Version.TryParse isn't capable of parsing digits without dots, for ex., 1 if (vals.Length == 1) { int n; if (!int.TryParse(vals[0], out n)) { AndroidLogcatInternalLog.Log("Failed to parse android OS version '{0}'", versionString); return(new Version(0, 0)); } return(new Version(n, 0)); } Version version; if (!Version.TryParse(versionString, out version)) { AndroidLogcatInternalLog.Log("Failed to parse android OS version '{0}'", versionString); return(new Version(0, 0)); } return(version); #endif }
protected void OnEnableInternal(AndroidLogcatRuntimeBase runtime) { AndroidLogcatInternalLog.Log("OnEnable"); m_Runtime = runtime; if (m_SearchField == null) { m_SearchField = new SearchField(); } m_Runtime.ProjectSettings.Tags.TagSelectionChanged += TagSelectionChanged; m_TimeOfLastAutoConnectStart = DateTime.Now; m_Runtime.Update += OnUpdate; m_FinishedAutoselectingPackage = false; AndroidLogcatInternalLog.Log("Package: {0}, Auto select: {1}", PlayerSettings.applicationIdentifier, AutoSelectPackage); m_StatusBar = new AndroidLogcatStatusBar(); m_Runtime.Settings.OnSettingsChanged += OnSettingsChanged; m_MemoryViewer = new AndroidLogcatMemoryViewer(this, m_Runtime); // Can't apply settings here, apparently EditorStyles aren't initialized yet. m_ApplySettings = true; m_Runtime.DeviceQuery.Clear(); m_Runtime.DeviceQuery.DeviceSelected += OnSelectedDevice; // Since Runtime.OnDisable can be called earlier than this window OnClose, we must ensure the order m_Runtime.Closing += OnDisable; }
private void OnEnable() { AndroidLogcatInternalLog.Log("OnEnable"); m_Runtime = AndroidLogcatManager.instance.Runtime; if (m_SearchField == null) { m_SearchField = new SearchField(); } if (m_TagControl == null) { m_TagControl = new AndroidLogcatTagsControl(); } m_TagControl.TagSelectionChanged += TagSelectionChanged; m_SelectedDeviceIndex = -1; m_SelectedDeviceId = null; m_TimeOfLastAutoConnectStart = DateTime.Now; m_Runtime.OnUpdate += Update; m_FinishedAutoselectingPackage = false; AndroidLogcatInternalLog.Log("Package: {0}, Auto select: {1}", PlayerSettings.applicationIdentifier, AutoSelectPackage); m_StatusBar = new AndroidLogcatStatusBar(); m_Runtime.Settings.OnSettingsChanged += OnSettingsChanged; // Can't apply settings here, apparently EditorStyles aren't initialized yet. m_ApplySettings = true; }
private void OnDeviceDisconnected(string deviceId) { StopLogCat(); var msg = "Either adb.exe crashed or device disconnected (device id: " + GetDeviceDetailsFor(deviceId) + ")"; AndroidLogcatInternalLog.Log(msg); var index = m_DeviceIds.IndexOf(deviceId); if (index == -1) { return; } m_DeviceIds.RemoveAt(index); ArrayUtility.RemoveAt(ref m_DeviceDetails, index); m_SelectedDeviceIndex = -1; m_SelectedDeviceId = null; if (m_DeviceIds.Count > 0) { SetSelectedDeviceByIndex(0, true); } else { UpdateStatusBar(msg); } }
public static string GetPackageNameFromPid(AndroidBridge.ADB adb, IAndroidLogcatDevice device, int processId) { if (device == null) { return(string.Empty); } try { // Note: Flag -o doesn't work on Android 5.0 devices (tested on LGE LG-D620, 5.0.2) string cmd = string.Format("-s {0} shell ps -p {1}", device.Id, processId); AndroidLogcatInternalLog.Log("{0} {1}", adb.GetADBPath(), cmd); var output = adb.Run(new[] { cmd }, "Unable to get the package name for pid " + processId); if (string.IsNullOrEmpty(output)) { return(string.Empty); } var result = ProcessOutputFromPS(output); if (string.IsNullOrEmpty(result)) { AndroidLogcatInternalLog.Log("Unable to get the package name for pid " + processId + "\nOutput:\n" + output); } return(result); } catch (Exception ex) { AndroidLogcatInternalLog.Log(ex.Message); return(string.Empty); } }
/// <summary> /// Return the pid of the given package on the given device. /// </summary> public static int GetPidFromPackageName(AndroidBridge.ADB adb, IAndroidLogcatDevice device, string packageName) { if (device == null) return -1; try { string cmd = null; if (device.SupportsFilteringByPid) cmd = string.Format("-s {0} shell pidof -s {1}", device.Id, packageName); else cmd = string.Format("-s {0} shell ps", device.Id); AndroidLogcatInternalLog.Log("{0} {1}", adb.GetADBPath(), cmd); var output = adb.Run(new[] { cmd }, "Unable to get the pid of the given packages."); if (string.IsNullOrEmpty(output)) return -1; if (device.SupportsFilteringByPid) { AndroidLogcatInternalLog.Log(output); return int.Parse(output); } return ParsePidInfo(packageName, output); } catch (Exception ex) { AndroidLogcatInternalLog.Log(ex.Message); return -1; } }
private static void IntegrateConnectToDevice(IAndroidLogcatTaskResult result) { var r = (AndroidLogcatConnectToDeviceResult)result; AndroidLogcatInternalLog.Log(r.message); EditorUtility.ClearProgressBar(); EditorUtility.DisplayDialog(r.success ? "Success" : "Failure", r.message, "Ok"); }
private void DisconnectDevice(IAndroidLogcatDevice device) { var command = "disconnect " + device.Id; AndroidLogcatInternalLog.Log("adb " + command); var result = m_Runtime.Tools.ADB.Run(new[] { command }, "Failed to disconnect " + device.Id); AndroidLogcatInternalLog.Log(result); }
private void Update() { if (m_DeviceIds != null && m_DeviceIds.Count == 0) UpdateConnectedDevicesList(false); if (m_DeviceIds.Count == 0) return; if (m_AutoSelectPackage && !m_FinishedAutoselectingPackage) { // This is for AutoRun triggered by "Build And Run". if ((DateTime.Now - m_TimeOfLastAutoConnectUpdate).TotalMilliseconds < kMillisecondsBetweenConsecutiveAutoConnectChecks) return; AndroidLogcatInternalLog.Log("Waiting for {0} launch, elapsed {1} seconds", PlayerSettings.applicationIdentifier, (DateTime.Now - m_TimeOfLastAutoConnectStart).Seconds); m_TimeOfLastAutoConnectUpdate = DateTime.Now; ResetPackages(m_DeviceIds[0]); int projectApplicationPid = GetPidFromPackageName(PlayerSettings.applicationIdentifier, m_DeviceIds[0]); var package = CreatePackageInformation(PlayerSettings.applicationIdentifier, projectApplicationPid, m_DeviceIds[0]); if (package != null) { AndroidLogcatInternalLog.Log("Auto selecting package {0}", PlayerSettings.applicationIdentifier); // Note: Don't call SelectPackage as that will reset m_AutoselectPackage m_SelectedPackage = package; m_SelectedDeviceIndex = 0; m_SelectedDeviceId = m_DeviceIds[m_SelectedDeviceIndex]; RestartLogCat(); m_FinishedAutoselectingPackage = true; UpdateStatusBar(); } else { var timeoutMS = (DateTime.Now - m_TimeOfLastAutoConnectStart).TotalMilliseconds; if (timeoutMS > kMillisecondsMaxAutoconnectTimeOut) { var msg = string.Format("Timeout {0} ms while waiting for '{1}' to launch.", timeoutMS, PlayerSettings.applicationIdentifier); UpdateStatusBar(msg); AndroidLogcatInternalLog.Log(msg); m_FinishedAutoselectingPackage = true; } } } else { if (m_SelectedDeviceId == null) { int selectedDeviceIndex; PackageInformation selectedPackage; GetSelectedDeviceIndex(out selectedDeviceIndex, out selectedPackage); SetSelectedDeviceByIndex(selectedDeviceIndex, true); SelectPackage(selectedPackage); } } }
private void OnLogcatDisconnected(IAndroidLogcatDevice device) { StopLogCat(); var msg = "Either adb application crashed or device disconnected (device id: " + device.DisplayName + ")"; AndroidLogcatInternalLog.Log(msg); m_Runtime.DeviceQuery.UpdateConnectedDevicesList(true); UpdateStatusBar(msg); }
private void OnDisable() { if (m_Runtime.Settings != null) { m_Runtime.Settings.OnSettingsChanged -= OnSettingsChanged; } StopLogCat(); m_Runtime.OnUpdate -= Update; AndroidLogcatInternalLog.Log("OnDisable, Auto select: {0}", m_AutoSelectPackage); }
internal void Clear() { if (m_MessageProvider != null) { throw new InvalidOperationException("Cannot clear logcat when logcat process is alive."); } AndroidLogcatInternalLog.Log("{0} -s {1} logcat -c", adb.GetADBPath(), Device.Id); var adbOutput = adb.Run(new[] { "-s", Device.Id, "logcat", "-c" }, "Failed to clear logcat."); AndroidLogcatInternalLog.Log(adbOutput); }
string CopyIP(string deviceId) { var command = "-s " + deviceId + " shell ip route"; AndroidLogcatInternalLog.Log("adb " + command); var result = m_Runtime.Tools.ADB.Run(new[] { command }, "Failed to query ip"); AndroidLogcatInternalLog.Log(result); var ip = ParseIPAddress(result); return(string.IsNullOrEmpty(ip) ? "Failed to get IP address" : ip); }
internal string[] RunAddr2Line(string symbolFilePath, string[] addresses) { // https://sourceware.org/binutils/docs/binutils/addr2line.html var args = "-C -f -p -e \"" + symbolFilePath + "\" " + string.Join(" ", addresses.ToArray()); AndroidLogcatInternalLog.Log($"\"{m_Addr2LinePath}\" {args}"); var result = Shell.RunProcess( m_Addr2LinePath, args); ValidateResult(result); return(result.GetStandardOut().Split(new[] { '\n', '\r' }, System.StringSplitOptions.RemoveEmptyEntries)); }
public static int ParseTopActivityPackageInfo(string commandOutput, out string packageName) { packageName = ""; if (string.IsNullOrEmpty(commandOutput)) { return(-1); } // Note: Regex is very slow, looping through string is much faster string line = null; using (var sr = new StringReader(commandOutput)) { do { while ((line = sr.ReadLine()) != null) { if (line.Contains("top-activity") || // Top Activity when device is not locked line.Contains("top-sleeping")) // Top Activity when device is locked { break; } } if (string.IsNullOrEmpty(line)) { AndroidLogcatInternalLog.Log("Cannot find top activity."); return(-1); } AndroidLogcatInternalLog.Log(line); var reg = new Regex(@"(?<pid>\d+)\:(?<package>\S+)\/\S+\s+\(top-\S+\)"); var match = reg.Match(line); if (!match.Success) { AndroidLogcatInternalLog.Log("Match '{0}' failed.", line); return(-1); } int pid = int.Parse(match.Groups["pid"].Value); // There can be lines with (top-activity) at the end, but pid == 0, not sure what are those, but definetly not top activities if (pid > 0) { packageName = match.Groups["package"].Value; return(pid); } // Continue looking for top activity }while (true); } }
private void OnDisable() { if (m_TagControl.TagWindow != null) { m_TagControl.TagWindow.Close(); m_TagControl.TagWindow = null; } StopLogCat(); EditorApplication.update -= Update; AndroidLogcatInternalLog.Log("OnDisable, Auto select: {0}", m_AutoSelectPackage); }
private void SelectPackage(PackageInformation newPackage) { if ((m_SelectedPackage == null && newPackage == null) || (newPackage != null && m_SelectedPackage != null && newPackage.name == m_SelectedPackage.name && newPackage.processId == m_SelectedPackage.processId)) return; m_AutoSelectPackage = false; m_SelectedPackage = newPackage; RestartLogCat(); AndroidLogcatInternalLog.Log("Selecting pacakge {0}", newPackage == null ? "<null>" : newPackage.displayName); }
void ResolveStacktraces(string symbolPath, Regex regex) { m_ResolvedStacktraces = String.Empty; if (string.IsNullOrEmpty(m_Text)) { m_ResolvedStacktraces = string.Format(" <color={0}>(Please add some log with addresses first)</color>", m_RedColor); return; } var lines = m_Text.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); foreach (var l in lines) { string address; string library; if (!ParseLine(regex, l, out address, out library)) { m_ResolvedStacktraces += l; } else { string resolved = string.Format(" <color={0}>(Not resolved)</color>", m_RedColor); var symbolFile = GetSymbolFile(symbolPath, library); if (string.IsNullOrEmpty(symbolFile)) { resolved = string.Format(" <color={0}>({1} not found)</color>", m_RedColor, library); } else { try { var result = Addr2LineWrapper.Run("\"" + symbolFile + "\"", new[] { address }); AndroidLogcatInternalLog.Log("addr2line \"{0}\" {1}", symbolFile, address); if (!string.IsNullOrEmpty(result[0])) { resolved = string.Format(" <color={0}>({1})</color>", m_GreenColor, result[0].Trim()); } } catch (Exception ex) { m_ResolvedStacktraces = string.Format("Exception while running addr2line ('{0}', {1}):\n{2}", symbolFile, address, ex.Message); return; } } m_ResolvedStacktraces += l.Replace(address, address + resolved); } m_ResolvedStacktraces += Environment.NewLine; } }