Update shared Gaia workflows and Sargo development tooling

Fix camera switching and Contacts/SMS activity routing across shared hosts.
Integrate Marketplace installation and native standalone recovery tools,
Bluetooth runtime packages and trusted certificates.

Update English/French READMEs and the shared changelog with tested scope
and remaining radio/audio/Bluetooth limitations. Preview17 remains the
existing APK; no new native image is released.

Validation: shared JavaScript and native Python tests; Android packaging
and payload parity from an isolated publication checkout.
This commit is contained in:
OverSu 2026-10-08 14:27:17 +02:00
commit 0041cd9660
101 changed files with 3883 additions and 335 deletions

View file

@ -0,0 +1,7 @@
export class VulpesMarketplaceChild extends JSWindowActorChild {
handleEvent() {
const scope={};
Services.scriptloader.loadSubScript('resource://vulpes/host/marketplace-page.js',scope);
scope.installMarketplacePage(this.contentWindow,url=>this.sendAsyncMessage('Marketplace:Download',{url}));
}
}

View file

@ -0,0 +1,13 @@
import { Runtime } from 'resource://vulpes/host/Runtime.sys.mjs';
import { Views } from 'resource://vulpes/host/Views.sys.mjs';
import { packageURL } from 'resource://vulpes/services/packages.mjs';
export class VulpesMarketplaceParent extends JSWindowActorParent {
receiveMessage(message) {
if(message.name!=='Marketplace:Download' || this.manager.documentPrincipal.originNoSuffix!=='https://vulpes-os.org')return;
const view=[...Views.entries.values()].find(v=>v.browser.browsingContext.top.id===this.browsingContext.top.id);
if(!view || !Runtime.identity(view.actor))return;
Runtime.marketplaceDownload=packageURL(message.data.url);
const app=Runtime.apps.find(a=>a.id==='marketplace');
Runtime.broadcast('launch',{manifestURL:app.manifestURL,origin:app.origin,url:app.origin+'/index.html',timestamp:Date.now()},'system');
}
}

View file

@ -141,6 +141,27 @@ export class VulpesChild extends JSWindowActorChild {
}
receiveMessage(message) {
if(message.name==='Vulpes:Edit') return this.edit(message.data);
if (message.name === 'Vulpes:ViewState') {
const frame = Array.from(this.document.querySelectorAll('iframe')).find(
f => f.browsingContext?.id === message.data.contextId);
if (!frame?.isConnected) return {visible:false};
const win = this.contentWindow, rect = frame.getBoundingClientRect();
const visible = !this.document.hidden && frame.checkVisibility({checkOpacity:true,checkVisibilityCSS:true}) &&
[[.5,.5],[.05,.05],[.95,.05],[.05,.95],[.95,.95]].every(([x,y]) =>
this.document.elementFromPoint(rect.left+rect.width*x,rect.top+rect.height*y)===frame);
let top = Math.max(0,rect.top);
// Gaia's status bar belongs above all app content, including native web views.
if (this.document.location.hostname === 'system.localhost') {
const bar=this.document.getElementById('statusbar');
if (bar?.checkVisibility({checkOpacity:true,checkVisibilityCSS:true})) {
const r=bar.getBoundingClientRect();
if (r.width>0 && r.bottom>top && r.top<=top) top=r.bottom;
}
}
return {visible,left:Math.max(0,rect.left)+win.mozInnerScreenX,
top:top+win.mozInnerScreenY,right:Math.min(win.innerWidth,rect.right)+win.mozInnerScreenX,
bottom:Math.min(win.innerHeight,rect.bottom)+win.mozInnerScreenY};
}
if (message.name === 'Vulpes:ViewAlive') {
return Array.from(this.document.querySelectorAll('iframe')).some(
(frame) => frame.isConnected && frame.browsingContext?.id === message.data.contextId,