summaryrefslogtreecommitdiff
path: root/Runtime/Export/CrashReporter.txt
blob: 2f689c9754dd7aaba1a6a43847f2c0f914723002 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
C++RAW

#include "UnityPrefix.h"
#include "Runtime/Misc/BuildSettings.h"
#include "Runtime/Scripting/ScriptingUtility.h"

CSRAW
using System;
using System.Collections.Generic;

namespace UnityEngine
{

CLASS CrashReport
	CSRAW static List<CrashReport> internalReports;
	CSRAW static object reportsLock = new object();

	CSRAW static int Compare(CrashReport c1, CrashReport c2)
	{
		long t1 = c1.time.Ticks;
		long t2 = c2.time.Ticks;
		if (t1 > t2)
			return 1;
		if (t1 < t2)
			return -1;
		return 0;
	}

	CSRAW static void PopulateReports()
	{
		lock (reportsLock)
		{
			if (internalReports != null)
				return;

			string[] ids = GetReports();
			internalReports = new List<CrashReport>(ids.Length);
			foreach (var id in ids)
			{
				double secondsSinceUnixEpoch;
				string text;
				GetReportData(id, out secondsSinceUnixEpoch, out text);
				DateTime time = new DateTime(1970, 1, 1).AddSeconds(secondsSinceUnixEpoch);
				internalReports.Add(new CrashReport(id, time, text));
			}
			internalReports.Sort(Compare);
		}
	}

	CSRAW public static CrashReport[] reports
	{
		get
		{
			PopulateReports();
			lock (reportsLock)
			{
				return internalReports.ToArray();
			}
		}
	}

	CSRAW public static CrashReport lastReport
	{
		get
		{
			PopulateReports();
			lock (reportsLock)
			{
				if (internalReports.Count > 0)
				{
					return internalReports[internalReports.Count - 1];
				}
			}

			return null;
		}
	}

	CSRAW public static void RemoveAll()
	{
		foreach (var report in reports)
			report.Remove();
	}
 
	CSRAW readonly string id;
	CSRAW public readonly DateTime time;
	CSRAW public readonly string text;

	CSRAW CrashReport(string id, DateTime time, string text)
	{
		this.id = id;
		this.time = time;
		this.text = text;
	}

	CSRAW public void Remove()
	{
		if (RemoveReport(id))
		{
			lock (reportsLock)
			{
				internalReports.Remove(this);
			}
		}
	}

	THREAD_SAFE CUSTOM private static string[] GetReports()
	{
		if (!GetBuildSettings().hasAdvancedVersion)
		{
			ErrorString("Crash reports are only supported in Unity Pro.");
			std::vector<std::string> reports;
			return Scripting::StringVectorToMono(reports);
		}

#if UNITY_IPHONE
		extern ScriptingArrayPtr GetCrashReports();
		return GetCrashReports();
#else
		std::vector<std::string> reports;
		return Scripting::StringVectorToMono(reports);
#endif
	}

	THREAD_SAFE CUSTOM private static void GetReportData(string id, out double secondsSinceUnixEpoch, out string text)
	{
#if UNITY_IPHONE
		extern void GetCrashReportData(ICallString id, double* secondsSinceUnixEpoch, ICallString* text);
		GetCrashReportData(id, secondsSinceUnixEpoch, text);
#else
		*secondsSinceUnixEpoch = 0.0;
#if !UNITY_WINRT && !UNITY_FLASH
		text->str = scripting_string_new("");
#endif
#endif
	}

	THREAD_SAFE CUSTOM private static bool RemoveReport(string id)
	{
#if UNITY_IPHONE
		extern bool RemoveCrashReport(ICallString id);
		return RemoveCrashReport(id);
#else
		return false;
#endif
	}
END

CSRAW
}