bug 1269998 - Prompt users with pending crash reports to submit them r=mconley ui-r=shorlander

This commit is contained in:
Brad Lassey 2016-05-10 23:50:55 -07:00
Родитель 5d418de2b6
Коммит 25f5af3107
3 изменённых файлов: 150 добавлений и 0 удалений

Просмотреть файл

@ -124,6 +124,11 @@ XPCOMUtils.defineLazyModuleGetter(this, "TabCrashHandler",
if (AppConstants.MOZ_CRASHREPORTER) {
XPCOMUtils.defineLazyModuleGetter(this, "PluginCrashReporter",
"resource:///modules/ContentCrashHandlers.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "CrashSubmit",
"resource://gre/modules/CrashSubmit.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "PluralForm",
"resource://gre/modules/PluralForm.jsm");
}
XPCOMUtils.defineLazyGetter(this, "gBrandBundle", function() {
@ -821,6 +826,57 @@ BrowserGlue.prototype = {
}
},
checkForPendingCrashReports: function() {
// We don't process crash reports older than 28 days, so don't bother submitting them
let numDays = 28;
if (AppConstants.MOZ_CRASHREPORTER) {
let dateLimit = new Date();
dateLimit.setDate(dateLimit.getDate() - numDays);
CrashSubmit.pendingIDsAsync(dateLimit).then(
function onSuccess(ids) {
let count = ids.length;
if (count) {
let win = RecentWindow.getMostRecentBrowserWindow();
let nb = win.document.getElementById("global-notificationbox");
let notification = nb.getNotificationWithValue("pending-crash-reports");
if (notification) {
return;
}
let buttons = [
{
label: win.gNavigatorBundle.getString("pendingCrashReports.submitAll"),
callback: function() {
ids.forEach(function(id) {
CrashSubmit.submit(id, {extraExtraKeyVals: {"SubmittedFromInfobar": true}});
});
}
},
{
label: win.gNavigatorBundle.getString("pendingCrashReports.ignoreAll"),
callback: function() {
ids.forEach(function(id) {
CrashSubmit.ignore(id);
});
}
},
{
label: win.gNavigatorBundle.getString("pendingCrashReports.viewAll"),
callback: function() {
win.openUILinkIn("about:crashes", "tab");
}
}
];
nb.appendNotification(PluralForm.get(count,
win.gNavigatorBundle.getString("pendingCrashReports.label")).replace("#1", count),
"pending-crash-reports",
"chrome://browser/skin/tab-crashed.svg",
nb.PRIORITY_INFO_HIGH, buttons);
}
}
);
}
},
_onSafeModeRestart: function BG_onSafeModeRestart() {
// prompt the user to confirm
let strings = gBrowserBundle;
@ -1071,6 +1127,10 @@ BrowserGlue.prototype = {
this._checkForOldBuildUpdates();
if ("release" != AppConstants.MOZ_UPDATE_CHANNEL) {
this.checkForPendingCrashReports();
}
this._firstWindowTelemetry(aWindow);
this._firstWindowLoaded();
},

Просмотреть файл

@ -760,6 +760,11 @@ certErrorDetailsCertChain.label = Certificate chain:
tabgroups.migration.anonGroup = Group %S
tabgroups.migration.tabGroupBookmarkFolderName = Bookmarked Tab Groups
pendingCrashReports.label = You have an unsubmitted crash report;You have #1 unsubmitted crash reports
pendingCrashReports.viewAll = View
pendingCrashReports.submitAll = Submit
pendingCrashReports.ignoreAll = Ignore
decoder.noCodecs.button = Learn how
decoder.noCodecs.accesskey = L
decoder.noCodecs.message = To play video, you may need to install Microsofts Media Feature Pack.

Просмотреть файл

@ -11,6 +11,8 @@ Cu.importGlobalProperties(['File']);
XPCOMUtils.defineLazyModuleGetter(this, "PromiseUtils",
"resource://gre/modules/PromiseUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "OS",
"resource://gre/modules/osfile.jsm");
this.EXPORTED_SYMBOLS = [
"CrashSubmit"
@ -23,6 +25,8 @@ const SUCCESS = "success";
const FAILED = "failed";
const SUBMITTING = "submitting";
const UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
var reportURL = null;
var strings = null;
var myListener = null;
@ -475,6 +479,29 @@ this.CrashSubmit = {
}
},
/**
* Add a .dmg.ignore file along side the .dmp file to indicate that the user
* shouldn't be prompted to submit this crash report again.
*
* @param id
* Filename (minus .dmp extension) of the report to ignore
*/
ignore: function CrashSubmit_ignore(id) {
let [dump, extra, mem] = getPendingMinidump(id);
return new Promise(
function (resolve, reject) {
let promise = OS.File.open(dump.path + ".ignore", {create: true}, {unixFlags:OS.Constants.libc.O_CREAT});
promise.then(
function createSuccess(file) {
file.close();
resolve();
}
);
}
)
},
/**
* Get the list of pending crash IDs.
*
@ -485,6 +512,64 @@ this.CrashSubmit = {
return getAllPendingMinidumpsIDs();
},
/**
* Get the list of pending crash IDs, exluding those marked to be ignored
* @param maxFileDate
* A Date object. Any files last modified before that date will be ignored
*
* @return a Promise that is fulfilled with an array of string, each
* being an ID as expected to be passed to submit() or ignore()
*/
pendingIDsAsync: function CrashSubmit_pendingIDsAsync(maxFileDate) {
let promise = new Promise(function(resolve, reject) {
OS.File.stat(getDir("pending").path).then(
function onSuccess(info) {
if (info.isDir) {
let iterator = new OS.File.DirectoryIterator(getDir("pending").path);
let ids = [];
iterator.forEach(
function onEntry(file) {
if (file.name.endsWith(".dmp")) {
return OS.File.exists(file.path + ".ignore").then(
function onSuccess(ignoreExists) {
if (!ignoreExists) {
let id = file.name.slice(0, -4);
if (UUID_REGEX.test(id)) {
return OS.File.stat(file.path).then(
function onSuccess(info) {
if (info.lastAccessDate.valueOf() > maxFileDate.valueOf()) {
ids.push(id);
}
}
);
}
}
}
);
}
}
).then(
function onSuccess() {
iterator.close();
resolve(ids);
},
function onError(err) {
iterator.close();
reject(err);
}
);
} else {
reject();
}
},
function onError(err) {
reject(err);
}
)
});
return promise;
},
/**
* Prune the saved dumps.
*/