Release Vulpes OS 2.7-preview.22

This commit is contained in:
OverSu 2026-10-22 20:42:26 +02:00
commit a138f97877
294 changed files with 515786 additions and 187 deletions

View file

@ -15,6 +15,11 @@ import org.mozilla.geckoview.*;
public final class MainActivity extends Activity {
void updateTrackingProtection(boolean enabled) {
if (gaia != null) gaia.getSettings().setUseTrackingProtection(enabled);
if (web != null) web.getSettings().setUseTrackingProtection(enabled);
}
private VulpesApplication app;
private GeckoSession gaia, web;
private GeckoView gaiaView, webView;
@ -130,6 +135,7 @@ public final class MainActivity extends Activity {
? app.gaiaSession
: new GeckoSession(
new GeckoSessionSettings.Builder()
.useTrackingProtection(app.trackingProtection)
.displayMode(GeckoSessionSettings.DISPLAY_MODE_STANDALONE)
.build()
);
@ -216,7 +222,8 @@ public final class MainActivity extends Activity {
return;
}
if (web == null) {
web = new GeckoSession();
web = new GeckoSession(new GeckoSessionSettings.Builder()
.useTrackingProtection(app.trackingProtection).build());
web.setContentDelegate(content);
web.setPromptDelegate(prompts);
web.setPermissionDelegate(permissions);

View file

@ -20,6 +20,7 @@ public final class VulpesApplication extends Application {
boolean pendingScreenLock;
boolean homeVisible;
boolean homeAtBottom;
boolean trackingProtection = true;
@Override
public void onCreate() {
@ -66,6 +67,8 @@ public final class VulpesApplication extends Application {
.locales(new String[] { "fr", "en-US" })
.automaticFontSizeAdjustment(false)
.fontInflation(false)
.contentBlocking(new ContentBlocking.Settings.Builder()
.antiTracking(ContentBlocking.AntiTracking.DEFAULT).build())
.build()
);
services = new AndroidServices(this);
@ -104,6 +107,12 @@ public final class VulpesApplication extends Application {
return GeckoResult.fromException(new SecurityException("EXTENSION_REQUIRED"));
}
JSONObject json = (JSONObject) message;
if (json.optString("type").equals("privacy.configure")) {
trackingProtection = json.optBoolean("enabled", true);
if (gaiaSession != null) gaiaSession.getSettings().setUseTrackingProtection(trackingProtection);
if (activity != null) activity.updateTrackingProtection(trackingProtection);
return GeckoResult.fromValue(null);
}
if (json.optString("type").equals("marketplace.return") && activity!=null) {activity.runOnUiThread(()->activity.closeBrowser());return GeckoResult.fromValue(null);}
if (json.optString("type").startsWith("packages.")) {
GeckoResult<Object> result=new GeckoResult<>();

View file

@ -3,7 +3,7 @@ import {Input} from './services/input.mjs';
import { Packages, packageURL } from './services/packages.mjs';
import { Activities, isGaiaActivity } from './services/activities.mjs';
import { authorizePlatform } from './services/platform.mjs';
import { SettingsService } from './services/settings.mjs';
import { SettingsService, migrateSearchDefaults, migratePrivacyDefaults } from './services/settings.mjs';
import { DataStoreService } from './services/datastores.mjs';
import { DataStoresIndexedDB } from './adapters/datastores-indexeddb.mjs';
import { Contacts } from './Contacts.mjs';
@ -35,7 +35,7 @@ function grants(app) {
function broadcast(type, data, target) {
for (const peer of peers) {
if (target && peer.app.id !== target) continue;
if (type === 'settingchange' && !['language.current', 'vulpes.theme'].includes(data.key) && !grants(peer.app).includes('settings.read')) continue;
if (type === 'settingchange' && !['language.current', 'vulpes.theme', 'vulpes.layout'].includes(data.key) && !grants(peer.app).includes('settings.read')) continue;
if (
type === 'contactchange' &&
!peer.app.manifest.permissions?.contacts?.access?.includes('read')
@ -80,6 +80,12 @@ const ready = (async () => {
const defaults = await (await fetch('defaults.json')).json();
const saved = await browser.storage.local.get('settings');
values = { ...defaults, ...saved.settings };
const privacyChanged = migratePrivacyDefaults(values);
if (migrateSearchDefaults(values) || privacyChanged) {
await browser.storage.local.set({settings:values});
}
await browser.runtime.sendNativeMessage('vulpes', {type:'privacy.configure',
enabled:values['privacy.trackingprotection.enabled'] === true});
if (!values['vulpes.gaia-restoration.v1']) {
values['lockscreen.enabled'] = true;
values['vulpes.gaia-restoration.v1'] = true;
@ -106,6 +112,8 @@ const ready = (async () => {
await browser.storage.local.set({ settings: next });
values = next;
for (const [key, value] of entries) {
if (key === 'privacy.trackingprotection.enabled')
await browser.runtime.sendNativeMessage('vulpes', {type:'privacy.configure',enabled:value === true});
broadcast('settingchange', { key, value });
if(key==='keyboard.gaia.enabled') {
input.hide();broadcast('input-mode',{enabled:value===true});
@ -333,6 +341,7 @@ async function handle(peer, request) {
}
if (method === 'input.config') return values['keyboard.gaia.enabled'] === true;
if (method === 'input.request') return input.request(peer,params);
if (method === 'layout.current') return {mode:values['vulpes.layout'] || 'auto', compactDefault:false};
if (method === 'appearance.current') return values['vulpes.theme'] || 'light';
if (method === 'locale.current') return values['language.current'] || 'en-US';
if (method === 'settings.snapshot') {
@ -541,7 +550,8 @@ let marketplaceDownload=null;
browser.runtime.onMessage.addListener(async (message,sender)=>{
if(!message.marketplaceDownload)return;
const origin=new URL(sender.url);
if(origin.origin!=='https://vulpes-os.org' || !origin.pathname.startsWith('/marketplace/'))throw Error('PERMISSION_DENIED');
if(!((origin.origin==='https://vulpes-os.org' && origin.pathname.startsWith('/marketplace/')) ||
(origin.origin==='https://ffapps.danielherr.software' && origin.pathname.startsWith('/app/'))))throw Error('PERMISSION_DENIED');
await ready;marketplaceDownload=packageURL(message.marketplaceDownload);
const app=apps.find(a=>a.id==='marketplace');launch(app);
await browser.runtime.sendNativeMessage('vulpes',{type:'marketplace.return'});

View file

@ -13,7 +13,8 @@
"nativeMessaging",
"geckoViewAddons",
"http://*.localhost/*",
"https://vulpes-os.org/*"
"https://vulpes-os.org/*",
"https://ffapps.danielherr.software/*"
],
"background": {
"page": "background.html",
@ -33,7 +34,8 @@
},
{
"matches": [
"https://vulpes-os.org/marketplace/*"
"https://vulpes-os.org/marketplace/*",
"https://ffapps.danielherr.software/app/*"
],
"js": [
"marketplace-page.js",

View file

@ -45,7 +45,7 @@ try:
const values={};window.nativeCalls=[];window.events=[];
window.browser={storage:{local:{get:async key=>({[key]:structuredClone(values[key])}),set:async data=>Object.assign(values,structuredClone(data))}},runtime:{
connectNative:()=>({onMessage:{addListener(fn){window.nativeEvent=fn;}},onDisconnect:{addListener(){}},postMessage(){}}),
sendNativeMessage:async(app,message)=>{nativeCalls.push(message);return message.type==='android.snapshot'?{}:null;},onConnect:{addListener(fn){window.connectPort=fn;}}
sendNativeMessage:async(app,message)=>{nativeCalls.push(message);if(message.type==='packages.list')return '[]';return message.type==='android.snapshot'?{}:null;},onConnect:{addListener(fn){window.connectPort=fn;}},onMessage:{addListener(){}}
}};
window.makePort=url=>{
let receive,seq=0;const waiting=new Map();