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:
parent
d04824ec89
commit
0041cd9660
101 changed files with 3883 additions and 335 deletions
41
host/settings-codec.js
Normal file
41
host/settings-codec.js
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
// Settings persistence and Android RPC use JSON. Preserve binary Gaia values across
|
||||
// both boundaries and reconstruct Blobs in the application's own JS realm.
|
||||
(() => {
|
||||
const marker = '__vulpesBlobV1';
|
||||
async function encode(value) {
|
||||
if (value instanceof Date) return value.toJSON();
|
||||
if (value instanceof Blob) {
|
||||
if (value.size > 16 * 1024 * 1024) throw new Error('SETTING_BLOB_TOO_LARGE');
|
||||
const bytes = new Uint8Array(await value.arrayBuffer());
|
||||
const chunks = [];
|
||||
for (let i = 0; i < bytes.length; i += 16384) {
|
||||
chunks.push(String.fromCharCode(...bytes.subarray(i, i + 16384)));
|
||||
}
|
||||
return { [marker]: true, type: value.type, base64: btoa(chunks.join('')) };
|
||||
}
|
||||
if (Array.isArray(value)) return Promise.all(value.map(encode));
|
||||
if (value && typeof value === 'object') {
|
||||
return Object.fromEntries(
|
||||
await Promise.all(
|
||||
Object.entries(value).map(async ([key, item]) => [key, await encode(item)]),
|
||||
),
|
||||
);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
function decode(value) {
|
||||
if (!value || typeof value !== 'object' || value instanceof Blob || value instanceof Date) return value;
|
||||
if (
|
||||
value[marker] === true &&
|
||||
typeof value.type === 'string' &&
|
||||
typeof value.base64 === 'string' &&
|
||||
Object.keys(value).length === 3
|
||||
) {
|
||||
const bytes = Uint8Array.from(atob(value.base64), (c) => c.charCodeAt(0));
|
||||
return new Blob([bytes], { type: value.type });
|
||||
}
|
||||
if (Array.isArray(value)) return value.map(decode);
|
||||
return Object.fromEntries(Object.entries(value).map(([key, item]) => [key, decode(item)]));
|
||||
}
|
||||
window.VulpesSettingsCodec = Object.freeze({ encode, decode });
|
||||
})();
|
||||
Loading…
Reference in a new issue