зеркало из https://github.com/mozilla/glean.git
Merge pull request #23 from Dexterp37/core_metrics
Add a few core metrics
This commit is contained in:
Коммит
6553128441
|
@ -6,16 +6,18 @@ package mozilla.telemetry.glean
|
|||
|
||||
import android.util.Log
|
||||
import android.content.Context
|
||||
import com.sun.jna.StringArray
|
||||
import mozilla.telemetry.glean.private.Lifetime
|
||||
import android.content.pm.PackageManager
|
||||
import android.os.Build
|
||||
import mozilla.components.service.glean.utils.getLocaleTag
|
||||
import java.io.File
|
||||
import mozilla.telemetry.glean.rust.LibGleanFFI
|
||||
import mozilla.telemetry.glean.rust.MetricHandle
|
||||
import mozilla.telemetry.glean.rust.RustError
|
||||
import org.mozilla.glean_rs.GleanMetrics.GleanBaseline
|
||||
import org.mozilla.glean_rs.GleanMetrics.GleanInternalMetrics
|
||||
|
||||
open class GleanInternalAPI internal constructor () {
|
||||
// `internal` so this can be modified for testing
|
||||
internal var bool_metric: MetricHandle = 0L
|
||||
internal var handle: MetricHandle = 0L
|
||||
|
||||
/**
|
||||
|
@ -34,16 +36,10 @@ open class GleanInternalAPI internal constructor () {
|
|||
|
||||
handle = LibGleanFFI.INSTANCE.glean_initialize(dataDir.path, applicationContext.packageName)
|
||||
|
||||
val e = RustError.ByReference()
|
||||
val pings = listOf("baseline")
|
||||
val ffiPingsList = StringArray(pings.toTypedArray(), "utf-8")
|
||||
bool_metric = LibGleanFFI.INSTANCE.glean_new_boolean_metric(
|
||||
category = "glean",
|
||||
name = "enabled",
|
||||
send_in_pings = ffiPingsList,
|
||||
send_in_pings_len = pings.size,
|
||||
lifetime = Lifetime.Application.ordinal,
|
||||
err = e)
|
||||
// TODO: on glean-legacy we perform other actions before initialize the metrics (e.g.
|
||||
// init the engines), then init the core metrics, and finally kick off the metrics
|
||||
// schedulers. We should do something similar here as well.
|
||||
initializeCoreMetrics(applicationContext)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -58,6 +54,49 @@ open class GleanInternalAPI internal constructor () {
|
|||
return initialized.toInt() != 0
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the core metrics internally managed by Glean (e.g. client id).
|
||||
*/
|
||||
private fun initializeCoreMetrics(applicationContext: Context) {
|
||||
// Set a few more metrics that will be sent as part of every ping.
|
||||
// TODO: we should make sure to store the data below before any ping
|
||||
// is generated and sent. In a-c's Glean, we rely on the StorageEngine(s)
|
||||
// access to do so. Once we make the metric type API async, this won't work
|
||||
// anymore.
|
||||
GleanBaseline.locale.set(getLocaleTag())
|
||||
GleanInternalMetrics.os.set("Android")
|
||||
// https://developer.android.com/reference/android/os/Build.VERSION
|
||||
GleanInternalMetrics.androidSdkVersion.set(Build.VERSION.SDK_INT.toString())
|
||||
GleanInternalMetrics.osVersion.set(Build.VERSION.RELEASE)
|
||||
// https://developer.android.com/reference/android/os/Build
|
||||
GleanInternalMetrics.deviceManufacturer.set(Build.MANUFACTURER)
|
||||
GleanInternalMetrics.deviceModel.set(Build.MODEL)
|
||||
GleanInternalMetrics.architecture.set(Build.SUPPORTED_ABIS[0])
|
||||
|
||||
/*
|
||||
configuration.channel?.let {
|
||||
StringsStorageEngine.record(GleanInternalMetrics.appChannel, it)
|
||||
}*/
|
||||
|
||||
try {
|
||||
val packageInfo = applicationContext.packageManager.getPackageInfo(
|
||||
applicationContext.packageName, 0
|
||||
)
|
||||
@Suppress("DEPRECATION")
|
||||
GleanInternalMetrics.appBuild.set(packageInfo.versionCode.toString())
|
||||
|
||||
GleanInternalMetrics.appDisplayVersion.set(
|
||||
packageInfo.versionName?.let { it } ?: "Unknown"
|
||||
)
|
||||
} catch (e: PackageManager.NameNotFoundException) {
|
||||
Log.e(
|
||||
"glean-kotlin",
|
||||
"Could not get own package info, unable to report build id and display version"
|
||||
)
|
||||
throw AssertionError("Could not get own package info, aborting init")
|
||||
}
|
||||
}
|
||||
|
||||
fun collect(ping_name: String) {
|
||||
val e = RustError.ByReference()
|
||||
val s = LibGleanFFI.INSTANCE.glean_ping_collect(handle, ping_name, e)!!
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
package mozilla.components.service.glean.utils
|
||||
|
||||
import java.util.Locale
|
||||
|
||||
/**
|
||||
* Gets a gecko-compatible locale string (e.g. "es-ES" instead of Java [Locale]
|
||||
* "es_ES") for the default locale.
|
||||
*
|
||||
* This method approximates the API21 method [Locale.toLanguageTag].
|
||||
*
|
||||
* @return a locale string that supports custom injected locale/languages.
|
||||
*/
|
||||
internal fun getLocaleTag(): String {
|
||||
// Thanks to toLanguageTag() being introduced in API21, we could have
|
||||
// simple returned `locale.toLanguageTag();` from this function. However
|
||||
// what kind of languages the Android build supports is up to the manufacturer
|
||||
// and our apps usually support translations for more rare languages, through
|
||||
// our custom locale injector. For this reason, we can't use `toLanguageTag`
|
||||
// and must try to replicate its logic ourselves.
|
||||
val locale = Locale.getDefault()
|
||||
val language = getLanguageFromLocale(locale)
|
||||
val country = locale.country // Can be an empty string.
|
||||
return if (country.isEmpty()) language else "$language-$country"
|
||||
}
|
||||
|
||||
/**
|
||||
* Sometimes we want just the language for a locale, not the entire language
|
||||
* tag. But Java's .getLanguage method is wrong. A reference to the deprecated
|
||||
* ISO language codes and their mapping can be found in [Locale.toLanguageTag] docs.
|
||||
*
|
||||
* @param locale a [Locale] object to be stringified.
|
||||
* @return a language string, such as "he" for the Hebrew locales.
|
||||
*/
|
||||
internal fun getLanguageFromLocale(locale: Locale): String {
|
||||
// Can, but should never be, an empty string.
|
||||
val language = locale.language
|
||||
|
||||
// Modernize certain language codes.
|
||||
return when (language) {
|
||||
"iw" -> "he"
|
||||
"in" -> "id"
|
||||
"ji" -> "yi"
|
||||
else -> language
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче