in glean-core/android/src/main/java/mozilla/telemetry/glean/Glean.kt [176:272]
fun initialize(
applicationContext: Context,
uploadEnabled: Boolean,
configuration: Configuration = Configuration(),
buildInfo: BuildInfo,
) {
gleanEnableLogging()
configuration.dataPath?.let { safeDataPath ->
// When the `dataPath` is provided, we need to make sure:
// 1. The database path provided is not `glean_data`.
// 2. The database path is valid and writable.
// The default database path is `{context.applicationInfo.dataDir}/glean_data`,
// the background process and the main process cannot write to the same file.
if (safeDataPath == File(applicationContext.applicationInfo.dataDir, GLEAN_DATA_DIR).absolutePath) {
Log.e(
LOG_TAG,
"Attempted to initialize Glean with an invalid database path " +
"\"{context.applicationInfo.dataDir}/glean_data\" is reserved",
)
return
}
// Check that the database path we are trying to write to is valid and writable.
if (!canWriteToDatabasePath(safeDataPath)) {
Log.e(LOG_TAG, "Attempted to initialize Glean with an invalid database path")
return
}
this.gleanDataDir = File(safeDataPath)
this.isCustomDataPath = true
} ?: run {
// If no `dataPath` is provided, then we setup Glean as usual.
//
// If we don't initialize on the main thread lifecycle registration may fail when
// initializing on the main process.
ThreadUtils.assertOnUiThread()
// In certain situations Glean.initialize may be called from a process other than
// the main process. In this case we want initialize to be a no-op and just return.
//
// You can call Glean.initialize from a background process, but to do so you need
// to specify a dataPath in the Glean configuration.
if (!isMainProcess(applicationContext)) {
Log.e(
LOG_TAG,
"Attempted to initialize Glean on a process other than the main process without a dataPath",
)
return
}
this.gleanDataDir = File(applicationContext.applicationInfo.dataDir, GLEAN_DATA_DIR)
this.isCustomDataPath = false
}
if (isInitialized()) {
Log.e(LOG_TAG, "Glean should not be initialized multiple times")
return
}
this.buildInfo = buildInfo
this.applicationContext = applicationContext
this.configuration = configuration
this.httpClient = BaseUploader(configuration.httpClient)
// First flush the Kotlin-side queue.
// This will put things on the Rust-side queue, and thus keep them in the right order.
Dispatchers.Delayed.flushQueuedInitialTasks()
// Execute startup off the main thread.
Dispatchers.API.executeTask {
val cfg = InternalConfiguration(
dataPath = gleanDataDir.path,
applicationId = applicationContext.packageName,
languageBindingName = LANGUAGE_BINDING_NAME,
uploadEnabled = uploadEnabled,
maxEvents = null,
delayPingLifetimeIo = configuration.delayPingLifetimeIo,
appBuild = "none",
useCoreMps = false,
trimDataToRegisteredPings = false,
logLevel = configuration.logLevel,
rateLimit = null,
enableEventTimestamps = configuration.enableEventTimestamps,
experimentationId = configuration.experimentationId,
enableInternalPings = configuration.enableInternalPings,
pingSchedule = configuration.pingSchedule,
pingLifetimeThreshold = configuration.pingLifetimeThreshold.toULong(),
pingLifetimeMaxTime = configuration.pingLifetimeMaxTime.toULong(),
)
val clientInfo = getClientInfo(configuration, buildInfo)
val callbacks = OnGleanEventsImpl(this@GleanInternalAPI)
gleanInitialize(cfg, clientInfo, callbacks)
}
}