VulpesOS/gaia/tv_apps/smart-system/js/crash_reporter.js
OverSu b38dea0597 Publish Vulpes Preview 15 sources for desktop, Android and Tundra
Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
2026-09-30 23:13:03 +02:00

223 lines
6.8 KiB
JavaScript
Executable file

/* -*- Mode: js; js-indent-level: 2; indent-tabs-mode: nil -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
/* global SettingsCache, SystemBanner, focusManager */
'use strict';
// This file calls getElementById without waiting for an onload event, so it
// must have a defer attribute or be included at the end of the <body>.
window.CrashReporter = (function() {
var settings = navigator.mozSettings;
var screen = document.getElementById('screen');
// The name of the app that just crashed.
var crashedAppName = '';
// Whether or not to show a "Report" button in the banner.
var showReportButton = false;
// Only show the "Report" button if the user hasn't set a preference to
// always/never report crashes.
SettingsCache.observe('app.reportCrashes', 'ask',
function handleCrashSetting(value) {
showReportButton = (value != 'always' && value != 'never');
});
// This function should only ever be called once.
function showDialog(crashID, isChrome) {
var title = isChrome ? {
id: 'crash-dialog2-os',
args: null
} : {
id: 'crash-dialog-app',
args: { name: crashedAppName }
};
var crashDialogTitle = document.getElementById('crash-dialog-title');
navigator.mozL10n.setAttributes(crashDialogTitle, title.id, title.args);
// "Don't Send Report" button in dialog
var noButton = document.getElementById('dont-send-report');
noButton.addEventListener('click', function onNoButtonClick() {
settings.createLock().set({'app.reportCrashes': 'never'});
removeDialog();
});
// "Send Report" button in dialog
var yesButton = document.getElementById('send-report');
yesButton.addEventListener('click', function onYesButtonClick() {
submitCrash(crashID);
if (checkbox.checked) {
settings.createLock().set({'app.reportCrashes': 'always'});
}
removeDialog();
});
var checkbox = document.getElementById('always-send');
checkbox.addEventListener('click', function onCheckboxClick() {
// Disable the "Don't Send Report" button if the "Always send..."
// checkbox is checked
noButton.disabled = this.checked;
});
// "What's in a crash report?" link
var crashInfoLink = document.getElementById('crash-info-link');
crashInfoLink.addEventListener('click', function onLearnMoreClick() {
var dialog = document.getElementById('crash-dialog');
document.getElementById('crash-reports-header')
.addEventListener('action', function onAction() {
this.removeEventListener('click', onAction);
dialog.classList.remove('learn-more');
focusManager.focus();
});
dialog.classList.add('learn-more');
focusManager.focus();
});
screen.classList.add('crash-dialog');
}
// We can get rid of the dialog after it is shown once.
function removeDialog() {
screen.classList.remove('crash-dialog');
var dialog = document.getElementById('crash-dialog');
dialog.parentNode.removeChild(dialog);
focusManager.removeUI(window.CrashReporter);
focusManager.focus();
}
function showBanner(crashID, isChrome) {
var message = isChrome ? {
id: 'crash-banner-os2',
args: null
} : {
id: 'crash-banner-app',
args: { name: crashedAppName }
};
var button = null;
if (showReportButton) {
button = {
labelL10nId: 'crash-banner-report',
callback: function reportCrash() {
submitCrash(crashID);
},
dismiss: function dismissCrash() {
deleteCrash(crashID);
}
};
}
var systemBanner = new SystemBanner();
systemBanner.show(message, button);
}
function deleteCrash(crashID) {
var event = document.createEvent('CustomEvent');
event.initCustomEvent('mozContentEvent', true, true, {
type: 'delete-crash',
crashID: crashID
});
window.dispatchEvent(event);
}
function submitCrash(crashID) {
var event = document.createEvent('CustomEvent');
event.initCustomEvent('mozContentEvent', true, true, {
type: 'submit-crash',
crashID: crashID
});
window.dispatchEvent(event);
}
// - Show a dialog only the first time there's a crash to report.
// - On subsequent crashes, show a banner letting the user know there was a
// crash.
// - If the user hasn't set a pref, add a "Report" button to the banner.
function handleCrash(crashID, isChrome) {
// Check to see if we should show a dialog.
SettingsCache.get('crashReporter.dialogShown',
function dialogShownSuccess(value) {
var dialogShown = value;
if (!dialogShown) {
settings.createLock().set({'crashReporter.dialogShown': true});
showDialog(crashID, isChrome);
} else {
showBanner(crashID, isChrome);
}
focusManager.focus();
});
}
// We depend on window_manager.js calling this function before
// we get a 'handle-crash' event from shell.js
function setAppName(name) {
crashedAppName = name;
}
// We will be notified of system crashes from shell.js
window.addEventListener('mozChromeEvent', function handleChromeEvent(e) {
if (e.detail.type == 'handle-crash') {
handleCrash(e.detail.crashID, e.detail.chrome);
}
});
function handleAppCrash(e) {
var app = e.detail;
// Only show crash reporter when the crashed app is active.
if (app.isActive()) {
setAppName(app.name);
}
}
/**
* Determine whether there is crash-dialog or system banner focusable.
*/
function isFocusable() {
return document.getElementById('crash-dialog') &&
screen.classList.contains('crash-dialog');
}
/**
* Return parent container of crash report
*/
function getElement() {
var dialog = document.getElementById('crash-dialog');
if (isFocusable()) {
return dialog;
}
}
/**
* Focus send-report button if dialog is visible. If crash-reports-header is
* also visible, focus the actionButton in crash-reports-header
*/
function focus() {
var dialog = document.getElementById('crash-dialog');
var dialogButton = document.getElementById('send-report');
if (isFocusable() && dialogButton) {
document.activeElement.blur();
if (dialog.classList.contains('learn-more')) {
document.getElementById('crash-reports-header').els.actionButton
.focus();
} else {
dialogButton.focus();
}
}
}
window.addEventListener('appcrashed', handleAppCrash);
window.addEventListener('activitycrashed', handleAppCrash);
window.addEventListener('homescreencrashed', handleAppCrash);
window.addEventListener('searchcrashed', handleAppCrash);
return {
setAppName: setAppName,
isFocusable: isFocusable,
getElement: getElement,
focus: focus
};
})();
focusManager.addUI(window.CrashReporter);