Merge pull request #23 from Dexterp37/core_metrics

Add a few core metrics
This commit is contained in:
Alessio Placitelli 2019-05-09 16:42:07 +02:00 коммит произвёл GitHub
Родитель 701549c96b 291030c44b
Коммит 6553128441
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
2 изменённых файлов: 101 добавлений и 13 удалений

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

@ -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
}
}