Release Android Preview 21 and bilingual changelog

Add permission-based reading of Android contacts, SMS and call history. Include shared Gaia fixes and document device validation limits. Pixel image qualification remains pending.
This commit is contained in:
OverSu 2026-10-14 13:13:46 +02:00
commit 200d1fb235
43 changed files with 2271 additions and 65 deletions

View file

@ -86,7 +86,16 @@ define(function(require) {
var path = pathElement ? pathElement.dataset.path : null;
var panelFuncLoaded = function(panelFunc) {
var panel = panelFunc();
var panel;
try {
panel = panelFunc();
if (!panel || typeof panel.beforeShow !== 'function') {
throw new TypeError('Invalid settings panel: ' + panelId);
}
} catch (error) {
if (callback) callback(null, error);
return;
}
_panelCache[panelId] = panel;
if (callback) {
callback(panel);
@ -97,6 +106,8 @@ define(function(require) {
require([path], function(panelFunc) {
// Create a new panel object for static panels.
panelFuncLoaded(panelFunc ? panelFunc : SettingsPanel);
}, function(error) {
if (callback) callback(null, error);
});
} else {
panelFuncLoaded(SettingsPanel);

View file

@ -187,7 +187,12 @@ define(function(require) {
}
_loadPanel(panelId, function() {
PanelCache.get(panelId, function(panel) {
PanelCache.get(panelId, function(panel, loadError) {
if (loadError || !panel) {
console.error('Settings panel ' + panelId + ':', loadError);
callback(loadError || new Error('Missing settings panel: ' + panelId));
return;
}
var newPanelElement = document.getElementById(panelId);
var currentPanelId =
_currentNavigation && _currentNavigation.panelId;

View file

@ -408,14 +408,13 @@
var appStarter = AppStarter();
if (document.readyState !== 'loading') {
// Deferred Gaia components contain UMD wrappers. Finish loading them before
// Alameda starts, otherwise an anonymous component can become a panel module.
if (document.readyState === 'complete') {
appStarter.start();
} else {
document.addEventListener('readystatechange', function readyStateChange() {
if (document.readyState == 'interactive') {
document.removeEventListener('readystatechange', readyStateChange);
appStarter.start();
}
});
document.addEventListener('DOMContentLoaded', function() {
appStarter.start();
}, { once: true });
}
})();