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.
This commit is contained in:
OverSu 2026-09-30 23:13:03 +02:00
commit b38dea0597
25901 changed files with 9982925 additions and 369 deletions

View file

@ -0,0 +1,217 @@
'use strict';
// Utilities for sending data to the FxOS Telemetry Server
/* global asyncStorage, crypto, TextEncoder */
(function(exports) {
const DEFAULT_URL = 'https://fxos.telemetry.mozilla.org/submit/telemetry';
const DEFAULT_APPNAME = 'FirefoxOS';
const UNKNOWN = 'unknown';
const DOGFOOD_KEY = 'debug.performance_data.dogfooding';
const TR = TelemetryRequest;
// Set to true to enable debugging
TR.DEBUG = false;
// Create an XHR for the FxOS Telemetry Server.
// Arguments:
// args: Telemetry arguments
// - reason: 'reason' URL field (i.e 'ftu' or 'appusage'. required)
// - deviceID: unique ID tied to the device or request (required)
// - url: base URL for the telemetry server
// (default: https://fxos.telemetry.mozilla.org/submit/telemetry)
// - ver: Payload version (default: 1)
// - appName: appName URL field (default: FirefoxOS)
// - appUpdateChannel: update channel URL field (default: 'unknown')
// - appBuildID: buildID URL field (default 'unknown')
// - appVersion: app version URL field (default 'unknown')
// info: Arbitrary JSON serializable data that will be recorded by Telemetry
function TelemetryRequest(args, info) {
if (!args) {
throw new Error('No arguments');
}
if (!args.reason) {
throw new Error('No reason given');
}
if (!args.deviceID) {
throw new Error('No deviceID given');
}
// clone so we don't put data into the object that was given to us
this.info = info ? JSON.parse(JSON.stringify(info)) : {};
this.packet = {
ver: args.ver || 1,
info: this.info
};
this.info.reason = args.reason;
this.info.appName = args.appName || DEFAULT_APPNAME;
this.info.appUpdateChannel = args.appUpdateChannel || UNKNOWN;
this.info.appBuildID = args.appBuildID || UNKNOWN;
this.info.appVersion = args.appVersion || UNKNOWN;
var uriParts = [
args.url || DEFAULT_URL,
encodeURIComponent(args.deviceID),
encodeURIComponent(this.info.reason),
encodeURIComponent(this.info.appName),
encodeURIComponent(this.info.appVersion),
encodeURIComponent(this.info.appUpdateChannel),
encodeURIComponent(this.info.appBuildID)
];
this.url = uriParts.join('/');
}
function debug(...args) {
if (TR.DEBUG) {
args.unshift('[Telemetry]');
console.log.apply(console, args);
}
}
// Open and send the underlying XMLHttpRequest
// xhrAttrs: attributes to set on the XHR
// - timeout: The timeout for the request
// - onload / onerror / onabort / ontimeout: callbacks
TelemetryRequest.prototype.send = function(xhrAttrs) {
var xhr = new XMLHttpRequest({ mozSystem: true, mozAnon: true });
xhr.open('POST', this.url);
debug(this.url);
if (xhrAttrs && xhrAttrs.timeout) {
xhr.timeout = xhrAttrs.timeout;
}
xhr.setRequestHeader('Content-type', 'application/json');
xhr.responseType = 'text';
var data = JSON.stringify(this.packet);
xhr.send(data);
debug(data);
if (xhrAttrs) {
xhr.onload = xhrAttrs.onload;
xhr.onerror = xhrAttrs.onerror;
xhr.onabort = xhrAttrs.onabort;
xhr.ontimeout = xhrAttrs.ontimeout;
}
return xhr;
};
TelemetryRequest.getDeviceID = function(key) {
return new Promise(function(resolve, reject) {
if (!navigator.mozSettings) {
reject('Invalid mozSettings');
return;
}
var dogFood = navigator.mozSettings.createLock().get(DOGFOOD_KEY);
if (!dogFood) {
reject('Couldn\'t query ' + DOGFOOD_KEY);
return;
}
dogFood.onsuccess = function onSuccess() {
var isDogfooder = dogFood.result[DOGFOOD_KEY];
if (!isDogfooder && typeof key !== 'undefined') {
//return the stored uuid from the passed in key here
asyncStorage.getItem(key, function(value) {
if (value) {
resolve(value);
} else {
reject('No deviceID found');
}
});
} else {
var dialPromise = navigator.mozTelephony.dial('*#06#', 0);
dialPromise.then(function(call) {
return call.result;
}).then(function(result) {
// Check to make sure our telephony stack is initialized and
// has returned an imei.
if (result && result.success && (result.serviceCode === 'scImei')) {
return result.statusMessage;
} else {
reject('Unable to get IMEI');
}
}).then(function (imei) {
if (isDogfooder) {
resolve(imei);
} else {
return TelemetryRequest.createHash(imei);
}
}).then(function (hashed) {
resolve(hashed);
}).catch(reject);
}
};
});
};
TelemetryRequest.createHash = function createHash(id) {
return new Promise(function (resolve, reject) {
var salt = new Uint8Array([44, 27, 51, 17, 55, 64, 183, 55, 37, 31, 246,
196, 130, 73, 14, 95, 122, 241, 143, 18, 40, 109,
238, 59, 168, 82, 28, 199, 177, 37, 135, 98]);
var hexDigits = '0123456789ABCDEF';
var ftuID = '';
var macString = navigator.mozWifiManager.macAddress.replace(/:/g, '');
var bytes = new TextEncoder('utf-8').encode(id + macString);
crypto.subtle.importKey('raw', bytes, {name:'PBKDF2'},
false, ['deriveBits']).then(function (key) {
return crypto.subtle.deriveBits({
name: 'PBKDF2',
iterations: 1000,
salt: salt,
hash: 'SHA-1'
}, key, 160);
}).then(function (digest) {
var digestArray = new Uint8Array(digest).slice(0, 4);
digestArray.forEach(function(value) {
ftuID += (hexDigits[value >> 4] + hexDigits[value & 15]);
});
resolve(ftuID);
});
});
};
/*
* A utility function shared between telemetry modules that is used to get
* values for all of the specified settings. settingKeysAndDefaults is an
* object that maps settings keys to default values. We query the value of
* each of those settings and then create an object that maps keys to values
* (or to the default values) and pass that object to the callback function.
*/
TelemetryRequest.getSettings = function getSettings(settingKeysAndDefaults,
callback) {
var pendingQueries = 0;
var results = {};
var lock = window.navigator.mozSettings.createLock();
for (var key in settingKeysAndDefaults) {
var defaultValue = settingKeysAndDefaults[key];
query(key, defaultValue);
pendingQueries++;
}
function query(key, defaultValue) {
var request = lock.get(key);
request.onsuccess = function() {
var value = request.result[key];
if (value === undefined || value === null) {
value = defaultValue;
}
results[key] = value;
pendingQueries--;
if (pendingQueries === 0) {
callback(results);
}
};
}
};
exports.TelemetryRequest = TelemetryRequest;
}(window));