comparison components/nttBreakpadService.js @ 0:dada0ac40a8f

initial import
author Yoshiki Yazawa <yaz@honeyplanet.jp>
date Tue, 02 Dec 2008 20:31:01 +0900
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:dada0ac40a8f
1 const Cc = Components.classes;
2 const Ci = Components.interfaces;
3 const Cr = Components.results;
4
5 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
6
7 const LOAD_DELAY = 50;
8
9 Cc["@mozilla.org/moz/jssubscript-loader;1"]
10 .getService(Ci.mozIJSSubScriptLoader)
11 .loadSubScript("chrome://nightly/content/includes/tree-utils.js", null);
12
13 function BP_CreateArray(source)
14 {
15 var result = Cc["@mozilla.org/array;1"]
16 .createInstance(Ci.nsIMutableArray);
17
18 for (var key in source)
19 result.appendElement(source[key], false);
20
21 return result;
22 }
23
24 function nttBreakpadIncident(file)
25 {
26 this.id = file.leafName;
27 this.id = this.id.substring(0, this.id.length - 4);
28 this.date = file.lastModifiedTime;
29 this.file = file;
30 }
31
32 nttBreakpadIncident.prototype = {
33 date: null,
34 id: null,
35 file: null,
36
37 QueryInterface: XPCOMUtils.generateQI([Ci.nttIBreakpadIncident])
38 }
39
40 function nttBreakpadService() {
41 var obs = Cc["@mozilla.org/observer-service;1"]
42 .getService(Ci.nsIObserverService);
43 obs.addObserver(this, "quit-application", false);
44
45 this._dirs = [];
46 this._databases = [];
47 this._listeners = [];
48 this._incidents = [];
49 this._orderedIncidents = [];
50
51 this._findBreakpad();
52 if (this.reportdir)
53 this._dirs.push(this.reportdir);
54 else
55 {
56 this.loaded = true;
57 this._loading = true;
58 }
59 }
60
61 nttBreakpadService.prototype = {
62
63 reportdir: null,
64
65 loaded: false,
66 _loading: false,
67 _dirs: null,
68 _databases: null,
69 _loadTimer: null,
70 _listeners: null,
71
72 incidents: null,
73 orderedIncidents: null,
74
75 addProgressListener: function(listener)
76 {
77 if (!this.loaded)
78 this._listeners.push(listener);
79 else
80 listener.onDatabaseLoaded();
81 },
82
83 loadDatabase: function()
84 {
85 if (this._loading)
86 return;
87
88 this._loading = true;
89
90 if (this.reportdir && this.reportdir.exists())
91 {
92 this.incidents = [];
93 this.orderedIncidents = [];
94
95 this._loadTimer = Cc["@mozilla.org/timer;1"]
96 .createInstance(Ci.nsITimer);
97 this._loadTimer.init(this, LOAD_DELAY, Components.interfaces.nsITimer.TYPE_ONE_SHOT);
98 }
99 else
100 this.loaded = true;
101 },
102
103 observe: function(subject, topic, data)
104 {
105 switch (topic)
106 {
107 case "quit-application":
108 if (this._loadTimer)
109 {
110 // Shutdown during load, clear references
111 this._loadTimer.cancel();
112 this._loadTimer = null;
113 this._databases = [];
114 this._dirs = [];
115 this._listeners = [];
116 }
117 var obs = Cc["@mozilla.org/observer-service;1"]
118 .getService(Ci.nsIObserverService);
119 obs.removeObserver(this, "quit-application");
120 break;
121 case "timer-callback":
122 this.run();
123 break;
124 }
125 },
126
127 run: function()
128 {
129 if (this._dirs.length>0)
130 this._scanDir(this._dirs.pop());
131 else if (this._databases.length>0)
132 this._loadDatabase(this._databases.pop());
133 else
134 {
135 this.loaded = true;
136 if (this._listeners.length == 0) {
137 this._loadTimer = null;
138 return;
139 }
140 var listener = this._listeners.pop();
141 listener.onDatabaseLoaded();
142 if (this._listeners.length == 0) {
143 this._loadTimer = null;
144 return;
145 }
146 }
147 this._loadTimer.init(this, LOAD_DELAY, Components.interfaces.nsITimer.TYPE_ONE_SHOT);
148 },
149
150 _scanDir: function(dir)
151 {
152 var entries = dir.directoryEntries;
153 while (entries.hasMoreElements())
154 {
155 var ndir = entries.getNext().QueryInterface(Ci.nsIFile);
156 if (ndir.isDirectory())
157 this._dirs.push(ndir);
158 else
159 {
160 var ext = ndir.leafName;
161 ext = ext.substring(ext.length - 4);
162 if (ext == ".txt")
163 this._databases.push(ndir);
164 }
165 }
166 },
167
168 _loadDatabase: function(database)
169 {
170 var incident = new nttBreakpadIncident(database);
171 this._addIncident(incident);
172 },
173
174 _findBreakpad: function()
175 {
176 var directoryService = Cc["@mozilla.org/file/directory_service;1"]
177 .getService(Ci.nsIProperties);
178 var dir = directoryService.get("DefProfRt", Ci.nsIFile);
179 if (dir.leafName.toLowerCase() == "profiles")
180 dir = dir.parent;
181 dir.append("Crash Reports");
182 if (dir.exists() && dir.isDirectory())
183 this.reportdir = dir;
184 },
185
186 _addIncident: function(incident)
187 {
188 var pos = 0;
189 while ((pos < this.orderedIncidents.length) && (this.orderedIncidents[pos].date > incident.date))
190 pos++;
191
192 this.orderedIncidents.splice(pos, 0, incident);
193 this.incidents[incident.id]=incident;
194 },
195
196 getRecentIncidents: function(date)
197 {
198 var result = Cc["@mozilla.org/array;1"]
199 .createInstance(Ci.nsIMutableArray);
200
201 for (var i = 0; i < this.orderedIncidents.length; i++)
202 {
203 if (this.orderedIncidents[i].date<date)
204 break;
205
206 result.appendElement(this.orderedIncidents[i], false);
207 }
208
209 return result;
210 },
211
212 getPreviousIncidents: function(count)
213 {
214 var result = Cc["@mozilla.org/array;1"]
215 .createInstance(Ci.nsIMutableArray);
216
217 count=Math.min(count, this.orderedIncidents.length);
218
219 for (var i = 0; i < count; i++)
220 result.appendElement(this.orderedIncidents[i], false);
221
222 return result;
223 },
224
225 getIncident: function(id)
226 {
227 return this.incidents[id];
228 },
229
230 getIncidents: function()
231 {
232 return TB_CreateArray(this.orderedIncidents);
233 },
234
235 getTreeView: function()
236 {
237 var share = {};
238 var tv = new XULTreeView(share);
239 tv.childData.reserveChildren(true);
240
241 var vparent = tv.childData;
242
243 for (var i = 0; i < this.orderedIncidents.length; i++)
244 {
245 var incident = this.orderedIncidents[i];
246 record = new XULTreeViewRecord(share);
247 record.setColumnPropertyName("incidentID", "id");
248 record.setColumnPropertyName("incidentDate", "date");
249 record.setColumnProperties("incidentID", "name incident");
250 record.id = incident.id;
251 record.date = (new Date(incident.date)).toLocaleString();
252 tv.childData.appendChild(record);
253 }
254
255 return tv;
256 },
257
258 classDescription: "Nightly Tester Breakpad Service",
259 contractID: "@blueprintit.co.uk/breakpad;1",
260 classID: Components.ID("{b33388ca-71b4-4194-b822-2cbd0e89ffc0}"),
261 QueryInterface: XPCOMUtils.generateQI([Ci.nttIBreakpadService, Ci.nsIObserver])
262 }
263
264 function NSGetModule(compMgr, fileSpec)
265 XPCOMUtils.generateModule([nttBreakpadService]);