2019-01-24 21:07:52 +00:00
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
2019-07-12 18:38:15 +00:00
|
|
|
* 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/. */
|
2019-01-24 21:07:52 +00:00
|
|
|
|
2019-01-23 21:39:53 +00:00
|
|
|
package org.mozilla.fenix
|
|
|
|
|
2019-02-13 15:08:35 +00:00
|
|
|
import android.annotation.SuppressLint
|
2019-06-23 17:13:52 +00:00
|
|
|
import android.os.Build
|
|
|
|
import android.os.Build.VERSION.SDK_INT
|
2019-07-12 05:23:28 +00:00
|
|
|
import android.os.StrictMode
|
2019-11-22 13:18:50 +00:00
|
|
|
import androidx.annotation.CallSuper
|
2019-04-02 00:53:37 +00:00
|
|
|
import androidx.appcompat.app.AppCompatDelegate
|
2019-08-28 19:55:24 +00:00
|
|
|
import androidx.core.content.getSystemService
|
2019-05-02 15:59:13 +00:00
|
|
|
import kotlinx.coroutines.Deferred
|
2019-01-29 19:20:29 +00:00
|
|
|
import kotlinx.coroutines.Dispatchers
|
|
|
|
import kotlinx.coroutines.GlobalScope
|
2020-01-04 02:15:35 +00:00
|
|
|
import kotlinx.coroutines.async
|
|
|
|
import kotlinx.coroutines.launch
|
|
|
|
import kotlinx.coroutines.runBlocking
|
2019-07-17 22:09:47 +00:00
|
|
|
import mozilla.appservices.Megazord
|
2020-02-04 06:41:52 +00:00
|
|
|
import mozilla.components.browser.session.Session
|
2019-07-19 20:05:17 +00:00
|
|
|
import mozilla.components.concept.push.PushProcessor
|
2020-02-25 17:31:05 +00:00
|
|
|
import mozilla.components.feature.addons.update.GlobalAddonDependencyProvider
|
2020-01-15 23:31:51 +00:00
|
|
|
import mozilla.components.service.glean.Glean
|
|
|
|
import mozilla.components.service.glean.config.Configuration
|
|
|
|
import mozilla.components.service.glean.net.ConceptFetchHttpUploader
|
2019-01-29 19:20:29 +00:00
|
|
|
import mozilla.components.support.base.log.Log
|
|
|
|
import mozilla.components.support.base.log.logger.Logger
|
|
|
|
import mozilla.components.support.base.log.sink.AndroidLogSink
|
2019-03-14 13:27:54 +00:00
|
|
|
import mozilla.components.support.ktx.android.content.isMainProcess
|
|
|
|
import mozilla.components.support.ktx.android.content.runOnlyInMainProcess
|
2020-01-04 02:15:35 +00:00
|
|
|
import mozilla.components.support.locale.LocaleAwareApplication
|
2019-07-17 22:09:47 +00:00
|
|
|
import mozilla.components.support.rusthttp.RustHttpConfig
|
2019-02-15 21:19:14 +00:00
|
|
|
import mozilla.components.support.rustlog.RustLog
|
2020-03-26 00:36:31 +00:00
|
|
|
import mozilla.components.support.utils.logElapsedTime
|
2020-02-04 06:41:52 +00:00
|
|
|
import mozilla.components.support.webextensions.WebExtensionSupport
|
2020-03-12 01:11:33 +00:00
|
|
|
import org.mozilla.fenix.FeatureFlags.webPushIntegration
|
2019-01-23 21:39:53 +00:00
|
|
|
import org.mozilla.fenix.components.Components
|
2020-02-08 05:53:37 +00:00
|
|
|
import org.mozilla.fenix.components.metrics.MetricServiceType
|
2019-09-10 17:11:58 +00:00
|
|
|
import org.mozilla.fenix.ext.settings
|
2020-02-28 22:09:06 +00:00
|
|
|
import org.mozilla.fenix.push.PushFxaIntegration
|
2020-03-09 19:38:00 +00:00
|
|
|
import org.mozilla.fenix.push.WebPushEngineIntegration
|
2019-08-28 19:55:24 +00:00
|
|
|
import org.mozilla.fenix.session.NotificationSessionObserver
|
2020-01-23 08:24:48 +00:00
|
|
|
import org.mozilla.fenix.session.PerformanceActivityLifecycleCallbacks
|
2019-08-28 19:55:24 +00:00
|
|
|
import org.mozilla.fenix.session.VisibilityLifecycleCallback
|
2020-01-21 02:19:10 +00:00
|
|
|
import org.mozilla.fenix.utils.BrowsersCache
|
2020-02-23 17:57:04 +00:00
|
|
|
import org.mozilla.fenix.utils.Settings
|
2019-01-23 21:39:53 +00:00
|
|
|
|
2019-02-13 15:08:35 +00:00
|
|
|
@SuppressLint("Registered")
|
2020-02-28 20:37:08 +00:00
|
|
|
@Suppress("TooManyFunctions", "LargeClass")
|
2020-01-04 02:15:35 +00:00
|
|
|
open class FenixApplication : LocaleAwareApplication() {
|
2020-01-15 23:31:51 +00:00
|
|
|
private val logger = Logger("FenixApplication")
|
2019-01-29 19:20:29 +00:00
|
|
|
|
2019-05-07 21:36:37 +00:00
|
|
|
open val components by lazy { Components(this) }
|
2019-01-29 16:42:10 +00:00
|
|
|
|
2019-08-28 19:55:24 +00:00
|
|
|
var visibilityLifecycleCallback: VisibilityLifecycleCallback? = null
|
|
|
|
private set
|
|
|
|
|
2019-01-29 16:42:10 +00:00
|
|
|
override fun onCreate() {
|
|
|
|
super.onCreate()
|
2019-05-29 19:44:03 +00:00
|
|
|
|
2019-11-22 13:18:50 +00:00
|
|
|
setupInAllProcesses()
|
2019-01-29 16:42:10 +00:00
|
|
|
|
2019-03-14 13:27:54 +00:00
|
|
|
if (!isMainProcess()) {
|
2019-02-26 16:24:14 +00:00
|
|
|
// If this is not the main process then do not continue with the initialization here. Everything that
|
|
|
|
// follows only needs to be done in our app's main process and should not be done in other processes like
|
|
|
|
// a GeckoView child process or the crash handling process. Most importantly we never want to end up in a
|
2019-07-09 16:29:44 +00:00
|
|
|
// situation where we create a GeckoRuntime from the Gecko child process.
|
2019-02-26 16:24:14 +00:00
|
|
|
return
|
2019-02-13 15:08:35 +00:00
|
|
|
}
|
2019-02-26 16:24:14 +00:00
|
|
|
|
2020-01-23 16:06:04 +00:00
|
|
|
if (Config.channel.isFenix) {
|
|
|
|
// We need to always initialize Glean and do it early here.
|
|
|
|
// Note that we are only initializing Glean here for "fenix" builds. "fennec" builds
|
|
|
|
// will initialize in MigratingFenixApplication because we first need to migrate the
|
|
|
|
// user's choice from Fennec.
|
|
|
|
initializeGlean()
|
2020-01-22 12:37:52 +00:00
|
|
|
}
|
2020-01-23 16:06:04 +00:00
|
|
|
|
|
|
|
setupInMainProcessOnly()
|
|
|
|
}
|
|
|
|
|
|
|
|
protected fun initializeGlean() {
|
|
|
|
val telemetryEnabled = settings().isTelemetryEnabled
|
|
|
|
|
|
|
|
logger.debug("Initializing Glean (uploadEnabled=$telemetryEnabled, isFennec=${Config.channel.isFennec})")
|
|
|
|
|
2020-01-15 23:31:51 +00:00
|
|
|
Glean.initialize(
|
|
|
|
applicationContext = this,
|
|
|
|
configuration = Configuration(
|
|
|
|
channel = BuildConfig.BUILD_TYPE,
|
|
|
|
httpClient = ConceptFetchHttpUploader(
|
|
|
|
lazy(LazyThreadSafetyMode.NONE) { components.core.client }
|
|
|
|
)),
|
2020-01-23 16:06:04 +00:00
|
|
|
uploadEnabled = telemetryEnabled
|
2020-01-15 23:31:51 +00:00
|
|
|
)
|
2019-11-22 13:18:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@CallSuper
|
|
|
|
open fun setupInAllProcesses() {
|
|
|
|
setupCrashReporting()
|
|
|
|
|
|
|
|
// We want the log messages of all builds to go to Android logcat
|
|
|
|
Log.addSink(AndroidLogSink())
|
|
|
|
}
|
|
|
|
|
|
|
|
@CallSuper
|
|
|
|
open fun setupInMainProcessOnly() {
|
2019-11-23 20:35:17 +00:00
|
|
|
run {
|
|
|
|
// Attention: Do not invoke any code from a-s in this scope.
|
|
|
|
val megazordSetup = setupMegazord()
|
|
|
|
|
|
|
|
setDayNightTheme()
|
|
|
|
enableStrictMode()
|
2020-01-21 02:19:10 +00:00
|
|
|
warmBrowsersCache()
|
2019-11-23 20:35:17 +00:00
|
|
|
|
|
|
|
// Make sure the engine is initialized and ready to use.
|
|
|
|
components.core.engine.warmUp()
|
|
|
|
|
2020-02-04 06:41:52 +00:00
|
|
|
initializeWebExtensionSupport()
|
|
|
|
|
2019-11-23 20:35:17 +00:00
|
|
|
// Just to make sure it is impossible for any application-services pieces
|
|
|
|
// to invoke parts of itself that require complete megazord initialization
|
|
|
|
// before that process completes, we wait here, if necessary.
|
|
|
|
if (!megazordSetup.isCompleted) {
|
|
|
|
runBlocking { megazordSetup.await(); }
|
|
|
|
}
|
|
|
|
}
|
2019-08-01 14:20:45 +00:00
|
|
|
|
2019-02-13 15:08:35 +00:00
|
|
|
setupLeakCanary()
|
2019-09-24 17:33:46 +00:00
|
|
|
if (settings().isTelemetryEnabled) {
|
2020-02-08 05:53:37 +00:00
|
|
|
components.analytics.metrics.start(MetricServiceType.Data)
|
|
|
|
}
|
|
|
|
|
|
|
|
if (settings().isMarketingTelemetryEnabled) {
|
|
|
|
components.analytics.metrics.start(MetricServiceType.Marketing)
|
2019-04-03 18:59:08 +00:00
|
|
|
}
|
2019-07-19 20:05:17 +00:00
|
|
|
|
2019-08-27 21:15:38 +00:00
|
|
|
setupPush()
|
2019-08-28 19:55:24 +00:00
|
|
|
|
|
|
|
visibilityLifecycleCallback = VisibilityLifecycleCallback(getSystemService())
|
|
|
|
registerActivityLifecycleCallbacks(visibilityLifecycleCallback)
|
|
|
|
|
|
|
|
components.core.sessionManager.register(NotificationSessionObserver(this))
|
2019-09-24 17:50:11 +00:00
|
|
|
|
2019-12-16 23:13:45 +00:00
|
|
|
// Storage maintenance disabled, for now, as it was interfering with background migrations.
|
|
|
|
// See https://github.com/mozilla-mobile/fenix/issues/7227 for context.
|
|
|
|
// if ((System.currentTimeMillis() - settings().lastPlacesStorageMaintenance) > ONE_DAY_MILLIS) {
|
|
|
|
// runStorageMaintenance()
|
|
|
|
// }
|
2020-01-23 08:24:48 +00:00
|
|
|
|
|
|
|
registerActivityLifecycleCallbacks(
|
2020-03-27 06:12:00 +00:00
|
|
|
PerformanceActivityLifecycleCallbacks(components.performance.visualCompletenessQueue)
|
2020-01-23 08:24:48 +00:00
|
|
|
)
|
2020-03-19 19:24:23 +00:00
|
|
|
|
2020-03-27 06:12:00 +00:00
|
|
|
components.performance.visualCompletenessQueue.runIfReadyOrQueue {
|
2020-03-19 19:24:23 +00:00
|
|
|
GlobalScope.launch(Dispatchers.IO) {
|
2020-03-27 06:12:00 +00:00
|
|
|
logger.info("Running post-visual completeness tasks...")
|
2020-03-26 00:36:31 +00:00
|
|
|
logElapsedTime(logger, "Storage initialization") {
|
|
|
|
components.core.historyStorage.warmUp()
|
|
|
|
components.core.bookmarksStorage.warmUp()
|
|
|
|
components.core.passwordsStorage.warmUp()
|
|
|
|
}
|
2020-03-19 19:24:23 +00:00
|
|
|
}
|
|
|
|
}
|
2019-09-24 17:50:11 +00:00
|
|
|
}
|
|
|
|
|
2019-12-16 23:13:45 +00:00
|
|
|
// See https://github.com/mozilla-mobile/fenix/issues/7227 for context.
|
|
|
|
// To re-enable this, we need to do so in a way that won't interfere with any startup operations
|
|
|
|
// which acquire reserved+ sqlite lock. Currently, Fennec migrations need to write to storage
|
|
|
|
// on startup, and since they run in a background service we can't simply order these operations.
|
2019-09-24 17:50:11 +00:00
|
|
|
private fun runStorageMaintenance() {
|
|
|
|
GlobalScope.launch(Dispatchers.IO) {
|
|
|
|
// Bookmarks and history storage sit on top of the same db file so we only need to
|
|
|
|
// run maintenance on one - arbitrarily using bookmarks.
|
|
|
|
components.core.bookmarksStorage.runMaintenance()
|
|
|
|
}
|
2019-09-27 15:57:39 +00:00
|
|
|
settings().lastPlacesStorageMaintenance = System.currentTimeMillis()
|
2019-01-29 19:20:29 +00:00
|
|
|
}
|
|
|
|
|
2019-02-13 15:08:35 +00:00
|
|
|
protected open fun setupLeakCanary() {
|
|
|
|
// no-op, LeakCanary is disabled by default
|
|
|
|
}
|
|
|
|
|
2019-09-27 07:16:32 +00:00
|
|
|
open fun updateLeakCanaryState(isEnabled: Boolean) {
|
2019-02-13 15:08:35 +00:00
|
|
|
// no-op, LeakCanary is disabled by default
|
|
|
|
}
|
|
|
|
|
2019-08-27 20:12:29 +00:00
|
|
|
private fun setupPush() {
|
2019-08-27 21:15:38 +00:00
|
|
|
// Sets the PushFeature as the singleton instance for push messages to go to.
|
|
|
|
// We need the push feature setup here to deliver messages in the case where the service
|
|
|
|
// starts up the app first.
|
2020-02-28 22:09:06 +00:00
|
|
|
components.push.feature?.let {
|
2019-09-11 21:50:54 +00:00
|
|
|
Logger.info("AutoPushFeature is configured, initializing it...")
|
2019-08-27 21:15:38 +00:00
|
|
|
|
|
|
|
// Install the AutoPush singleton to receive messages.
|
2020-02-28 22:09:06 +00:00
|
|
|
PushProcessor.install(it)
|
|
|
|
|
2020-03-12 01:11:33 +00:00
|
|
|
if (webPushIntegration) {
|
|
|
|
// WebPush integration to observe and deliver push messages to engine.
|
|
|
|
WebPushEngineIntegration(components.core.engine, it).start()
|
|
|
|
}
|
2020-03-09 19:38:00 +00:00
|
|
|
|
2020-02-28 22:09:06 +00:00
|
|
|
// Perform a one-time initialization of the account manager if a message is received.
|
|
|
|
PushFxaIntegration(it, lazy { components.backgroundServices.accountManager }).launch()
|
2019-08-27 21:15:38 +00:00
|
|
|
|
|
|
|
// Initialize the service. This could potentially be done in a coroutine in the future.
|
2020-02-28 22:09:06 +00:00
|
|
|
it.initialize()
|
2019-08-27 21:15:38 +00:00
|
|
|
}
|
2019-08-27 20:12:29 +00:00
|
|
|
}
|
|
|
|
|
2019-01-29 16:42:10 +00:00
|
|
|
private fun setupCrashReporting() {
|
|
|
|
components
|
|
|
|
.analytics
|
|
|
|
.crashReporter
|
|
|
|
.install(this)
|
|
|
|
}
|
2019-02-15 21:19:14 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Initiate Megazord sequence! Megazord Battle Mode!
|
|
|
|
*
|
2020-02-25 21:09:02 +00:00
|
|
|
* The application-services combined libraries are known as the "megazord". We use the default `full`
|
|
|
|
* megazord - it contains everything that fenix needs, and (currently) nothing more.
|
|
|
|
*
|
|
|
|
* Documentation on what megazords are, and why they're needed:
|
2019-07-17 22:09:47 +00:00
|
|
|
* - https://github.com/mozilla/application-services/blob/master/docs/design/megazords.md
|
|
|
|
* - https://mozilla.github.io/application-services/docs/applications/consuming-megazord-libraries.html
|
2019-02-15 21:19:14 +00:00
|
|
|
*/
|
2019-11-23 20:35:17 +00:00
|
|
|
private fun setupMegazord(): Deferred<Unit> {
|
|
|
|
// Note: Megazord.init() must be called as soon as possible ...
|
2019-07-17 22:09:47 +00:00
|
|
|
Megazord.init()
|
2019-11-23 20:35:17 +00:00
|
|
|
|
|
|
|
return GlobalScope.async(Dispatchers.IO) {
|
|
|
|
// ... but RustHttpConfig.setClient() and RustLog.enable() can be called later.
|
|
|
|
RustHttpConfig.setClient(lazy { components.core.client })
|
|
|
|
RustLog.enable()
|
|
|
|
}
|
2019-02-15 21:19:14 +00:00
|
|
|
}
|
2019-02-26 16:24:14 +00:00
|
|
|
|
2019-03-14 13:27:54 +00:00
|
|
|
override fun onTrimMemory(level: Int) {
|
|
|
|
super.onTrimMemory(level)
|
2020-03-05 13:05:27 +00:00
|
|
|
|
2019-03-14 13:27:54 +00:00
|
|
|
runOnlyInMainProcess {
|
2020-03-05 13:05:27 +00:00
|
|
|
components.core.icons.onTrimMemory(level)
|
|
|
|
components.core.sessionManager.onTrimMemory(level)
|
2019-02-26 16:24:14 +00:00
|
|
|
}
|
|
|
|
}
|
2019-04-02 00:53:37 +00:00
|
|
|
|
2019-04-04 14:44:03 +00:00
|
|
|
@SuppressLint("WrongConstant")
|
|
|
|
// Suppressing erroneous lint warning about using MODE_NIGHT_AUTO_BATTERY, a likely library bug
|
2019-04-02 00:53:37 +00:00
|
|
|
private fun setDayNightTheme() {
|
2019-09-24 17:33:46 +00:00
|
|
|
val settings = this.settings()
|
2019-04-02 00:53:37 +00:00
|
|
|
when {
|
2019-06-23 17:13:52 +00:00
|
|
|
settings.shouldUseLightTheme -> {
|
2019-04-02 00:53:37 +00:00
|
|
|
AppCompatDelegate.setDefaultNightMode(
|
|
|
|
AppCompatDelegate.MODE_NIGHT_NO
|
|
|
|
)
|
|
|
|
}
|
2019-06-23 17:13:52 +00:00
|
|
|
settings.shouldUseDarkTheme -> {
|
2019-04-02 00:53:37 +00:00
|
|
|
AppCompatDelegate.setDefaultNightMode(
|
|
|
|
AppCompatDelegate.MODE_NIGHT_YES
|
|
|
|
)
|
|
|
|
}
|
2019-06-23 17:13:52 +00:00
|
|
|
SDK_INT < Build.VERSION_CODES.P && settings.shouldUseAutoBatteryTheme -> {
|
2019-04-02 00:53:37 +00:00
|
|
|
AppCompatDelegate.setDefaultNightMode(
|
|
|
|
AppCompatDelegate.MODE_NIGHT_AUTO_BATTERY
|
|
|
|
)
|
|
|
|
}
|
2019-06-23 17:13:52 +00:00
|
|
|
SDK_INT >= Build.VERSION_CODES.P && settings.shouldFollowDeviceTheme -> {
|
2019-04-02 00:53:37 +00:00
|
|
|
AppCompatDelegate.setDefaultNightMode(
|
|
|
|
AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
|
|
|
|
)
|
|
|
|
}
|
|
|
|
// First run of app no default set, set the default to Follow System for 28+ and Normal Mode otherwise
|
|
|
|
else -> {
|
2019-06-23 17:13:52 +00:00
|
|
|
if (SDK_INT >= Build.VERSION_CODES.P) {
|
2019-04-02 00:53:37 +00:00
|
|
|
AppCompatDelegate.setDefaultNightMode(
|
|
|
|
AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
|
|
|
|
)
|
2019-08-20 17:47:55 +00:00
|
|
|
settings.shouldFollowDeviceTheme = true
|
2019-04-02 00:53:37 +00:00
|
|
|
} else {
|
|
|
|
AppCompatDelegate.setDefaultNightMode(
|
|
|
|
AppCompatDelegate.MODE_NIGHT_NO
|
|
|
|
)
|
2019-08-20 17:47:55 +00:00
|
|
|
settings.shouldUseLightTheme = true
|
2019-04-02 00:53:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-07-12 05:23:28 +00:00
|
|
|
|
2020-01-21 02:19:10 +00:00
|
|
|
private fun warmBrowsersCache() {
|
|
|
|
// We avoid blocking the main thread for BrowsersCache on startup by loading it on
|
|
|
|
// background thread.
|
|
|
|
GlobalScope.launch(Dispatchers.Default) {
|
|
|
|
BrowsersCache.all(this@FenixApplication)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-07-12 05:23:28 +00:00
|
|
|
private fun enableStrictMode() {
|
2019-12-20 21:27:05 +00:00
|
|
|
if (Config.channel.isDebug) {
|
2019-07-12 05:23:28 +00:00
|
|
|
StrictMode.setThreadPolicy(
|
|
|
|
StrictMode.ThreadPolicy.Builder()
|
|
|
|
.detectAll()
|
|
|
|
.penaltyLog()
|
|
|
|
.build()
|
|
|
|
)
|
|
|
|
var builder = StrictMode.VmPolicy.Builder()
|
|
|
|
.detectLeakedSqlLiteObjects()
|
|
|
|
.detectLeakedClosableObjects()
|
|
|
|
.detectLeakedRegistrationObjects()
|
|
|
|
.detectActivityLeaks()
|
|
|
|
.detectFileUriExposure()
|
|
|
|
.penaltyLog()
|
2019-09-24 17:50:11 +00:00
|
|
|
if (SDK_INT >= Build.VERSION_CODES.O) builder =
|
|
|
|
builder.detectContentUriWithoutPermission()
|
2019-07-12 05:23:28 +00:00
|
|
|
if (SDK_INT >= Build.VERSION_CODES.P) builder = builder.detectNonSdkApiUsage()
|
|
|
|
StrictMode.setVmPolicy(builder.build())
|
|
|
|
}
|
|
|
|
}
|
2020-02-04 06:41:52 +00:00
|
|
|
|
|
|
|
private fun initializeWebExtensionSupport() {
|
|
|
|
try {
|
2020-02-25 17:31:05 +00:00
|
|
|
GlobalAddonDependencyProvider.initialize(
|
|
|
|
components.addonManager,
|
2020-02-27 14:42:13 +00:00
|
|
|
components.addonUpdater,
|
|
|
|
onCrash = { exception ->
|
|
|
|
components.analytics.crashReporter.submitCaughtException(exception)
|
|
|
|
}
|
2020-02-25 17:31:05 +00:00
|
|
|
)
|
2020-02-04 06:41:52 +00:00
|
|
|
WebExtensionSupport.initialize(
|
|
|
|
components.core.engine,
|
|
|
|
components.core.store,
|
|
|
|
onNewTabOverride = {
|
|
|
|
_, engineSession, url ->
|
2020-02-23 17:57:04 +00:00
|
|
|
val shouldCreatePrivateSession =
|
|
|
|
components.core.sessionManager.selectedSession?.private
|
|
|
|
?: Settings.instance?.openLinksInAPrivateTab
|
|
|
|
?: false
|
|
|
|
|
|
|
|
val session = Session(url, shouldCreatePrivateSession)
|
2020-02-04 06:41:52 +00:00
|
|
|
components.core.sessionManager.add(session, true, engineSession)
|
|
|
|
session.id
|
|
|
|
},
|
|
|
|
onCloseTabOverride = {
|
|
|
|
_, sessionId -> components.tabsUseCases.removeTab(sessionId)
|
|
|
|
},
|
|
|
|
onSelectTabOverride = {
|
|
|
|
_, sessionId ->
|
|
|
|
val selected = components.core.sessionManager.findSessionById(sessionId)
|
|
|
|
selected?.let { components.tabsUseCases.selectTab(it) }
|
2020-02-28 20:37:08 +00:00
|
|
|
},
|
|
|
|
onExtensionsLoaded = { extensions ->
|
|
|
|
components.addonUpdater.registerForFutureUpdates(extensions)
|
2020-03-09 19:23:57 +00:00
|
|
|
components.supportedAddChecker.registerForChecks()
|
2020-03-02 18:46:37 +00:00
|
|
|
},
|
|
|
|
onUpdatePermissionRequest = components.addonUpdater::onUpdatePermissionRequest
|
2020-02-04 06:41:52 +00:00
|
|
|
)
|
|
|
|
} catch (e: UnsupportedOperationException) {
|
|
|
|
Logger.error("Failed to initialize web extension support", e)
|
|
|
|
}
|
|
|
|
}
|
2019-02-26 16:24:14 +00:00
|
|
|
}
|