Bug 1626969 - Include locale in Glean pings.r=chutten,supply-chain-reviewers

Differential Revision: https://phabricator.services.mozilla.com/D185153
This commit is contained in:
Travis Long 2023-08-04 18:41:55 +00:00
Родитель a60cb82de8
Коммит de399e3600
27 изменённых файлов: 130 добавлений и 46 удалений

8
Cargo.lock сгенерированный
Просмотреть файл

@ -2205,9 +2205,9 @@ dependencies = [
[[package]]
name = "glean"
version = "53.1.0"
version = "53.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0efbf048a79e634cd5ccd224f972018e3f217c72d4071bbe6ebee382037bffcb"
checksum = "df470f5f41c8fc6113bd48fa18e0f1a8193e1e2b1f3942f8255b064e60db42ff"
dependencies = [
"chrono",
"crossbeam-channel",
@ -2225,9 +2225,9 @@ dependencies = [
[[package]]
name = "glean-core"
version = "53.1.0"
version = "53.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "826ac72df83806896eda459414972a0ca288d4d206811fd10a8a00a581b85498"
checksum = "6f72ce41516d772676db57c87fee1c99545bbda4b430793f24d0c81918cfbd8a"
dependencies = [
"android_logger",
"bincode",

Просмотреть файл

@ -36,7 +36,7 @@ allprojects {
topsrcdir = gradle.mozconfig.topsrcdir
topobjdir = gradle.mozconfig.topobjdir
gleanVersion = "53.1.0"
gleanVersion = "53.2.0"
if (gleanVersion != getRustVersionFor("glean")) {
throw new StopExecutionException("Mismatched Glean version, expected: ${gleanVersion}," +
" found ${getRustVersionFor("glean")}")

8
gfx/wr/Cargo.lock сгенерированный
Просмотреть файл

@ -987,9 +987,9 @@ dependencies = [
[[package]]
name = "glean"
version = "53.1.0"
version = "53.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0efbf048a79e634cd5ccd224f972018e3f217c72d4071bbe6ebee382037bffcb"
checksum = "df470f5f41c8fc6113bd48fa18e0f1a8193e1e2b1f3942f8255b064e60db42ff"
dependencies = [
"chrono",
"crossbeam-channel",
@ -1007,9 +1007,9 @@ dependencies = [
[[package]]
name = "glean-core"
version = "53.1.0"
version = "53.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "826ac72df83806896eda459414972a0ca288d4d206811fd10a8a00a581b85498"
checksum = "6f72ce41516d772676db57c87fee1c99545bbda4b430793f24d0c81918cfbd8a"
dependencies = [
"android_logger",
"bincode",

Просмотреть файл

@ -52,7 +52,7 @@ svg_fmt = "0.4"
tracy-rs = "0.1.2"
derive_more = { version = "0.99", default-features = false, features = ["add_assign"] }
etagere = "0.2.6"
glean = "53.1.0"
glean = "53.2.0"
firefox-on-glean = { version = "0.1.0", optional = true }
swgl = { path = "../swgl", optional = true }
topological-sort = "0.1"

Просмотреть файл

@ -25,7 +25,7 @@ tracy-rs = "0.1.2"
log = "0.4"
lazy_static = "1"
fxhash = "0.2.1"
glean = { version = "53.1.0", optional = true }
glean = { version = "53.2.0", optional = true }
firefox-on-glean = { version = "0.1.0", optional = true }
serde = { optional = true, version = "1.0", features = ["serde_derive"] }

Просмотреть файл

@ -6,7 +6,8 @@
Classes = [
{
'js_name': 'locale',
'name': 'Locale',
'js_name': 'locale',
'cid': '{92735ff4-6384-4ad6-8508-757010e149ee}',
'contract_ids': ['@mozilla.org/intl/localeservice;1'],
'interfaces': ['mozILocaleService'],

Просмотреть файл

@ -89,7 +89,7 @@ vendored:third_party/python/wheel
vendored:third_party/python/zipp
# glean-sdk may not be installable if a wheel isn't available
# and it has to be built from source.
pypi-optional:glean-sdk==53.1.0:telemetry will not be collected
pypi-optional:glean-sdk==53.2.0:telemetry will not be collected
# Mach gracefully handles the case where `psutil` is unavailable.
# We aren't (yet) able to pin packages in automation, so we have to
# support down to the oldest locally-installed version (5.4.2).

Просмотреть файл

@ -191,15 +191,15 @@ user-login = "jrmuizel"
user-name = "Jeff Muizelaar"
[[publisher.glean]]
version = "53.1.0"
when = "2023-06-28"
version = "53.2.0"
when = "2023-08-02"
user-id = 48
user-login = "badboy"
user-name = "Jan-Erik Rediger"
[[publisher.glean-core]]
version = "53.1.0"
when = "2023-06-28"
version = "53.2.0"
when = "2023-08-02"
user-id = 48
user-login = "badboy"
user-name = "Jan-Erik Rediger"
@ -1226,3 +1226,15 @@ criteria = "safe-to-deploy"
version = "1.4.0"
notes = "I have read over the macros, and audited the unsafe code."
aggregated-from = "https://raw.githubusercontent.com/mozilla/cargo-vet/main/supply-chain/audits.toml"
[[audits.mozilla.audits.time]]
who = "Kershaw Chang <kershaw@mozilla.com>"
criteria = "safe-to-deploy"
delta = "0.1.45 -> 0.3.17"
aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml"
[[audits.mozilla.audits.time-macros]]
who = "Kershaw Chang <kershaw@mozilla.com>"
criteria = "safe-to-deploy"
version = "0.2.6"
aggregated-from = "https://hg.mozilla.org/mozilla-central/raw-file/tip/supply-chain/audits.toml"

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

5
third_party/rust/glean-core/Cargo.toml поставляемый
Просмотреть файл

@ -13,7 +13,7 @@
edition = "2021"
rust-version = "1.62"
name = "glean-core"
version = "53.1.0"
version = "53.2.0"
authors = [
"Jan-Erik Rediger <jrediger@mozilla.com>",
"The Glean Team <glean-team@mozilla.com>",
@ -33,10 +33,9 @@ readme = "README.md"
keywords = ["telemetry"]
license = "MPL-2.0"
repository = "https://github.com/mozilla/glean"
resolver = "1"
[package.metadata.glean]
glean-parser = "7.1.0"
glean-parser = "8.1.0"
[dependencies.bincode]
version = "1.2.1"

Просмотреть файл

@ -1080,7 +1080,7 @@ mod test {
let metric_id_pattern = "telemetry_test.single_metric";
// Write sample metrics to the database.
let lifetimes = vec![Lifetime::User, Lifetime::Ping, Lifetime::Application];
let lifetimes = [Lifetime::User, Lifetime::Ping, Lifetime::Application];
for lifetime in lifetimes.iter() {
for value in &["retain", "delete"] {

Просмотреть файл

@ -894,7 +894,7 @@ mod test {
},
execution_counter: None,
};
let timestamps = vec![20, 40, 200];
let timestamps = [20, 40, 200];
let not_glean_restarted = StoredEvent {
event: RecordedEvent {
timestamp: timestamps[0],
@ -970,8 +970,8 @@ mod test {
// This scenario represents a run of three events followed by an hour between runs,
// followed by one final event.
let timestamps = vec![20, 40, 200, 12];
let ecs = vec![0, 1];
let timestamps = [20, 40, 200, 12];
let ecs = [0, 1];
let some_hour = 16;
let startup_date = FixedOffset::east(0)
.ymd(2022, 11, 24)
@ -1095,8 +1095,8 @@ mod test {
// This scenario represents a run of two events followed by negative one hours between runs,
// followed by two more events.
let timestamps = vec![20, 40, 12, 200];
let ecs = vec![0, 1];
let timestamps = [20, 40, 12, 200];
let ecs = [0, 1];
let some_hour = 10;
let startup_date = FixedOffset::east(0)
.ymd(2022, 11, 25)

2
third_party/rust/glean-core/tests/event.rs поставляемый
Просмотреть файл

@ -136,7 +136,7 @@ fn snapshot_correctly_clears_the_stores() {
let snapshot2 = glean
.event_storage()
.snapshot_as_json(&glean, "store2", false);
for s in vec![snapshot, snapshot2] {
for s in [snapshot, snapshot2] {
assert!(s.is_some());
let s = s.unwrap();
assert_eq!(1, s.as_array().unwrap().len());

2
third_party/rust/glean/.cargo-checksum.json поставляемый
Просмотреть файл

@ -1 +1 @@
{"files":{"Cargo.toml":"889c822c32b84930908f4280a9e73808cd0f57fa9f6cea2f9b61da017235e664","LICENSE":"1f256ecad192880510e84ad60474eab7589218784b9a50bc7ceee34c2b91f1d5","README.md":"5627cc81e6187ab6c2b4dff061af16d559edcab64ba786bac39daa69c703c595","src/common_test.rs":"de47b53dcca37985c0a2b8c02daecbf32309aa54f5a4dd9290719c2c1fd0fa55","src/configuration.rs":"c82d1d4c32baa878e0fae566c10cbe348531f2983657aee39276fd78ea0c9b1d","src/core_metrics.rs":"dd17b482613894af08b51a2cff6dc1e84a6dbd853c14a55566e6698348941ced","src/lib.rs":"727a078a27c4985adb4022f2fc64fda647c996078f995c1fec85c208cd3337bc","src/net/http_uploader.rs":"43812a70d19a38e8d7a093c8076c2b6345372c3c861b0f3511428762700a65e0","src/net/mod.rs":"e36e170a8e53530f8705988eea694ed7c55f50bb0ce403c0facbfb75ce03ac7f","src/private/event.rs":"02bbebf545695812e5055741cc0b5f3c99eda2039e684e26fcdd5f087ed15fe3","src/private/mod.rs":"eb8fe4e588bb32a54617324db39319920c627e6fc23c23cf4da5c17c63e0afed","src/private/ping.rs":"cbdc57f41fc9d46e56b4dfff91ac683753d1f8b3ecd0aa9bc3419e3595b8b81b","src/system.rs":"6eae5b41c15eba9cad6dbd116abe3519ee3e1fe034e79bdd692b029829a8c384","src/test.rs":"356890df8f88096b4a62e396d9810f9bc20790e7b7fb446c73801109ea1c26b1","tests/common/mod.rs":"37cd4c48e140c793b852ae09fb3e812da28a4412977295015bcbffd632fcf294","tests/init_fails.rs":"28fd7726e76ca1295eb0905eca0b2ec65b0accfa28432c9ff90ec8f92616fc79","tests/never_init.rs":"1f33b8ce7ca3514b57b48cc16d98408974c85cf8aa7d13257ffc2ad878ebb295","tests/no_time_to_init.rs":"e7df75b47897fbf2c860a2e1c1c225b57598b8d1a39125ca897fe8d825bf0338","tests/overflowing_preinit.rs":"7ad4b2274dd9240b53430859a4eb1d2597cf508a5a678333f3d3abbadd2ed4a7","tests/persist_ping_lifetime.rs":"81415dc1d74743f02269f0d0dfa524003147056853f080276972e64a0b761d3c","tests/persist_ping_lifetime_nopanic.rs":"18379d3ffbf4a2c8c684c04ff7a0660b86dfbbb447db2d24dfed6073cb7ddf8f","tests/schema.rs":"1b7b19aec54a24c2bdd4738cf33c16802c19c83504c4d0e6bcfc19142877acdb","tests/simple.rs":"b099034b0599bdf4650e0fa09991a8413fc5fbf397755fc06c8963d4c7c8dfa6","tests/test-shutdown-blocking.sh":"9b16a01c190c7062474dd92182298a3d9a27928c8fa990340fdd798e6cdb7ab2","tests/upload_timing.rs":"d044fce7c783133e385671ea37d674e5a1b4120cae7b07708dcd825addfa0ee3"},"package":"0efbf048a79e634cd5ccd224f972018e3f217c72d4071bbe6ebee382037bffcb"}
{"files":{"Cargo.toml":"6c5dc80704945076018237c096a850a6bd0d48d392e1f47e2d3437bdc673ea28","LICENSE":"1f256ecad192880510e84ad60474eab7589218784b9a50bc7ceee34c2b91f1d5","README.md":"5627cc81e6187ab6c2b4dff061af16d559edcab64ba786bac39daa69c703c595","src/common_test.rs":"de47b53dcca37985c0a2b8c02daecbf32309aa54f5a4dd9290719c2c1fd0fa55","src/configuration.rs":"5be1eaf4a2e1d1b35d9c13387f8f59b5f5d96a874b984396b7fae907e2938a8c","src/core_metrics.rs":"fef8fb4e5fa57c179836c6eb2cf59278fe3b8b036dbe57b0ff02971b4acd822f","src/lib.rs":"7bffe31c2b59d9e26b0869264af9a098be6eccb086f146e46777a288ad5e505f","src/net/http_uploader.rs":"43812a70d19a38e8d7a093c8076c2b6345372c3c861b0f3511428762700a65e0","src/net/mod.rs":"612a9f13ade0b202c8762bccc7b5dc288101cb3820e47be2755331911a221c55","src/private/event.rs":"02bbebf545695812e5055741cc0b5f3c99eda2039e684e26fcdd5f087ed15fe3","src/private/mod.rs":"eb8fe4e588bb32a54617324db39319920c627e6fc23c23cf4da5c17c63e0afed","src/private/ping.rs":"cbdc57f41fc9d46e56b4dfff91ac683753d1f8b3ecd0aa9bc3419e3595b8b81b","src/system.rs":"6eae5b41c15eba9cad6dbd116abe3519ee3e1fe034e79bdd692b029829a8c384","src/test.rs":"c877fa637e9049834818c3354f8b9b8b7a8136fb71ab3b0f9f0ea88115cbbd4b","tests/common/mod.rs":"08fb9483d9b6ed9fe873b4395245166ae8a15263be750c7a8e298c41d9604745","tests/init_fails.rs":"28fd7726e76ca1295eb0905eca0b2ec65b0accfa28432c9ff90ec8f92616fc79","tests/never_init.rs":"1f33b8ce7ca3514b57b48cc16d98408974c85cf8aa7d13257ffc2ad878ebb295","tests/no_time_to_init.rs":"e7df75b47897fbf2c860a2e1c1c225b57598b8d1a39125ca897fe8d825bf0338","tests/overflowing_preinit.rs":"7ad4b2274dd9240b53430859a4eb1d2597cf508a5a678333f3d3abbadd2ed4a7","tests/persist_ping_lifetime.rs":"81415dc1d74743f02269f0d0dfa524003147056853f080276972e64a0b761d3c","tests/persist_ping_lifetime_nopanic.rs":"18379d3ffbf4a2c8c684c04ff7a0660b86dfbbb447db2d24dfed6073cb7ddf8f","tests/schema.rs":"b1d78ac189c5f7309badbc37451fb428abce357e630a55e4ef5b0ef14d118f67","tests/simple.rs":"b099034b0599bdf4650e0fa09991a8413fc5fbf397755fc06c8963d4c7c8dfa6","tests/test-shutdown-blocking.sh":"9b16a01c190c7062474dd92182298a3d9a27928c8fa990340fdd798e6cdb7ab2","tests/test-thread-crashing.sh":"ff1bc8e5d7e4ba3a10d0d38bef222db8bfba469e7d30e45b1053d177a4084f09","tests/upload_timing.rs":"d044fce7c783133e385671ea37d674e5a1b4120cae7b07708dcd825addfa0ee3"},"package":"df470f5f41c8fc6113bd48fa18e0f1a8193e1e2b1f3942f8255b064e60db42ff"}

8
third_party/rust/glean/Cargo.toml поставляемый
Просмотреть файл

@ -13,7 +13,7 @@
edition = "2021"
rust-version = "1.62"
name = "glean"
version = "53.1.0"
version = "53.2.0"
authors = [
"Jan-Erik Rediger <jrediger@mozilla.com>",
"The Glean Team <glean-team@mozilla.com>",
@ -33,7 +33,6 @@ keywords = [
]
license = "MPL-2.0"
repository = "https://github.com/mozilla/glean"
resolver = "1"
[dependencies.chrono]
version = "0.4.10"
@ -43,7 +42,7 @@ features = ["serde"]
version = "0.5"
[dependencies.glean-core]
version = "53.1.0"
version = "53.2.0"
[dependencies.inherent]
version = "1"
@ -88,6 +87,9 @@ version = "1.0.19"
[dev-dependencies.jsonschema-valid]
version = "0.5.0"
[dev-dependencies.libc]
version = "0.2"
[dev-dependencies.tempfile]
version = "3.1.0"

4
third_party/rust/glean/src/configuration.rs поставляемый
Просмотреть файл

@ -39,7 +39,7 @@ pub struct Configuration {
/// The internal logging level.
pub log_level: Option<LevelFilter>,
/// The rate pings may be uploaded before they are throttled.
pub rate_limit: Option<glean_core::PingRateLimit>,
pub rate_limit: Option<crate::PingRateLimit>,
}
/// Configuration builder.
@ -79,7 +79,7 @@ pub struct Builder {
pub log_level: Option<LevelFilter>,
/// Optional: The internal ping upload rate limit.
/// Default: `None`
pub rate_limit: Option<glean_core::PingRateLimit>,
pub rate_limit: Option<crate::PingRateLimit>,
}
impl Builder {

4
third_party/rust/glean/src/core_metrics.rs поставляемый
Просмотреть файл

@ -13,6 +13,8 @@ pub struct ClientInfoMetrics {
pub app_display_version: String,
/// The product-provided release channel (e.g. "beta").
pub channel: Option<String>,
/// The locale of the application during initialization (e.g. "es-ES").
pub locale: Option<String>,
}
impl ClientInfoMetrics {
@ -22,6 +24,7 @@ impl ClientInfoMetrics {
app_build: "Unknown".to_string(),
app_display_version: "Unknown".to_string(),
channel: None,
locale: None,
}
}
}
@ -32,6 +35,7 @@ impl From<ClientInfoMetrics> for glean_core::ClientInfoMetrics {
app_build: metrics.app_build,
app_display_version: metrics.app_display_version,
channel: metrics.channel,
locale: metrics.locale,
os_version: system::get_os_version(),
windows_build_number: system::get_windows_build_number(),
architecture: system::ARCH.to_string(),

4
third_party/rust/glean/src/lib.rs поставляемый
Просмотреть файл

@ -36,8 +36,8 @@ pub use configuration::{Builder as ConfigurationBuilder, Configuration};
pub use core_metrics::ClientInfoMetrics;
pub use glean_core::{
metrics::{Datetime, DistributionData, MemoryUnit, Rate, RecordedEvent, TimeUnit, TimerId},
traits, CommonMetricData, Error, ErrorType, Glean, HistogramType, Lifetime, RecordedExperiment,
Result,
traits, CommonMetricData, Error, ErrorType, Glean, HistogramType, Lifetime, PingRateLimit,
RecordedExperiment, Result,
};
mod configuration;

23
third_party/rust/glean/src/net/mod.rs поставляемый
Просмотреть файл

@ -138,9 +138,26 @@ impl UploadManager {
Ordering::SeqCst,
Ordering::SeqCst,
);
})
.expect("Failed to spawn Glean's uploader thread");
*handle = Some(thread);
});
match thread {
Ok(thread) => *handle = Some(thread),
Err(err) => {
log::warn!("Failed to spawn Glean's uploader thread. This will be retried on next upload. Error: {err}");
// Swapping back the thread state. We're the ones setting it to `Running`, so
// should be able to set it back.
let state_change = self.inner.thread_running.compare_exchange(
State::Running,
State::Stopped,
Ordering::SeqCst,
Ordering::SeqCst,
);
if state_change.is_err() {
log::warn!("Failed to swap back thread state. Someone else jumped in and changed the state.");
}
}
};
}
pub(crate) fn shutdown(&self) {

2
third_party/rust/glean/src/test.rs поставляемый
Просмотреть файл

@ -1319,7 +1319,7 @@ fn configure_ping_throttling() {
})
.build();
let pings_per_interval = 10;
cfg.rate_limit = Some(glean_core::PingRateLimit {
cfg.rate_limit = Some(crate::PingRateLimit {
seconds_per_interval: 1,
pings_per_interval,
});

1
third_party/rust/glean/tests/common/mod.rs поставляемый
Просмотреть файл

@ -45,6 +45,7 @@ pub fn initialize(cfg: Configuration) {
app_build: "1.0.0".to_string(),
app_display_version: "1.0.0".to_string(),
channel: Some("testing".to_string()),
locale: Some("xx-XX".to_string()),
};
glean::initialize(cfg, client_info);

1
third_party/rust/glean/tests/schema.rs поставляемый
Просмотреть файл

@ -84,6 +84,7 @@ fn validate_against_schema() {
app_build: env!("CARGO_PKG_VERSION").to_string(),
app_display_version: env!("CARGO_PKG_VERSION").to_string(),
channel: Some("testing".to_string()),
locale: Some("xx-XX".to_string()),
};
glean::initialize(cfg, client_info);

32
third_party/rust/glean/tests/test-thread-crashing.sh поставляемый Executable file
Просмотреть файл

@ -0,0 +1,32 @@
#!/bin/bash
# Test harness for testing the RLB processes from the outside.
#
# Some behavior can only be observed when properly exiting the process running Glean,
# e.g. when an uploader runs in another thread.
# On exit the threads will be killed, regardless of their state.
# Remove the temporary data path on all exit conditions
cleanup() {
if [ -n "$datapath" ]; then
rm -r "$datapath"
fi
}
trap cleanup INT ABRT TERM EXIT
tmp="${TMPDIR:-/tmp}"
datapath=$(mktemp -d "${tmp}/glean_long_running.XXXX")
RUSTFLAGS="-C panic=abort" \
RUST_LOG=debug \
cargo run --example crashing-threads -- "$datapath"
ret=$?
count=$(ls -1q "$datapath/pending_pings" | wc -l)
if [[ $ret -eq 0 ]] && [[ "$count" -eq 1 ]]; then
echo "test result: ok."
exit 0
else
echo "test result: FAILED."
exit 101
fi

Просмотреть файл

@ -6,7 +6,7 @@ edition = "2018"
license = "MPL-2.0"
[dependencies]
glean = "53.1.0"
glean = "53.2.0"
log = "0.4"
nserror = { path = "../../../xpcom/rust/nserror" }
nsstring = { path = "../../../xpcom/rust/nsstring" }

Просмотреть файл

@ -9,7 +9,7 @@ license = "MPL-2.0"
[dependencies]
bincode = "1.0"
chrono = "0.4.10"
glean = "53.1.0"
glean = "53.2.0"
inherent = "1.0.0"
log = "0.4"
nsstring = { path = "../../../../xpcom/rust/nsstring", optional = true }

Просмотреть файл

@ -47,6 +47,7 @@ fn setup_glean(tempdir: Option<tempfile::TempDir>) -> tempfile::TempDir {
app_build: "test-build".into(),
app_display_version: "1.2.3".into(),
channel: None,
locale: None,
};
glean::test_reset_glean(cfg, client_info, true);

Просмотреть файл

@ -10,7 +10,9 @@ use std::path::PathBuf;
use firefox_on_glean::{metrics, pings};
use nserror::{nsresult, NS_ERROR_FAILURE};
use nsstring::{nsACString, nsCString, nsString};
use xpcom::interfaces::{nsIFile, nsIPrefService, nsIProperties, nsIXULAppInfo, nsIXULRuntime};
use xpcom::interfaces::{
mozILocaleService, nsIFile, nsIPrefService, nsIProperties, nsIXULAppInfo, nsIXULRuntime,
};
use xpcom::{RefPtr, XpCom};
use glean::{ClientInfoMetrics, Configuration};
@ -127,12 +129,13 @@ fn build_configuration(
};
let data_path = PathBuf::from(&data_path_str);
let (app_build, app_display_version, channel) = get_app_info()?;
let (app_build, app_display_version, channel, locale) = get_app_info()?;
let client_info = ClientInfoMetrics {
app_build,
app_display_version,
channel: Some(channel),
locale: Some(locale),
};
log::debug!("Client Info: {:#?}", client_info);
@ -220,16 +223,18 @@ fn get_data_path() -> Result<String, nsresult> {
Ok(data_path)
}
/// Return a tuple of the build_id, app version, and build channel.
/// Return a tuple of the build_id, app version, build channel, and locale.
/// If the XUL Runtime isn't a XULAppInfo (e.g. in xpcshell),
/// build_id ad app_version will be "unknown".
/// Other problems result in an error being returned instead.
fn get_app_info() -> Result<(String, String, String), nsresult> {
fn get_app_info() -> Result<(String, String, String, String), nsresult> {
let xul: RefPtr<nsIXULRuntime> =
xpcom::components::XULRuntime::service().map_err(|_| NS_ERROR_FAILURE)?;
let pref_service: RefPtr<nsIPrefService> =
xpcom::components::Preferences::service().map_err(|_| NS_ERROR_FAILURE)?;
let locale_service: RefPtr<mozILocaleService> =
xpcom::components::Locale::service().map_err(|_| NS_ERROR_FAILURE)?;
let branch = xpcom::getter_addrefs(|p| {
// Safe because:
// * `null` is explicitly allowed per documentation
@ -261,6 +266,7 @@ fn get_app_info() -> Result<(String, String, String), nsresult> {
"unknown".to_owned(),
"unknown".to_owned(),
channel.to_string(),
"unknown".to_owned(),
))
}
};
@ -275,10 +281,18 @@ fn get_app_info() -> Result<(String, String, String), nsresult> {
app_info.GetVersion(&mut *version).to_result()?;
}
let mut locale = nsCString::new();
unsafe {
locale_service
.GetAppLocaleAsBCP47(&mut *locale)
.to_result()?;
}
Ok((
build_id.to_string(),
version.to_string(),
channel.to_string(),
locale.to_string(),
))
}