Skip to content

Commit

Permalink
Integrate new search code from Android Components into Fenix.
Browse files Browse the repository at this point in the history
  • Loading branch information
pocmo committed Nov 20, 2020
1 parent 2904ca8 commit 2b759e9
Show file tree
Hide file tree
Showing 47 changed files with 801 additions and 1,637 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,15 @@ import androidx.test.uiautomator.UiSelector
import androidx.test.uiautomator.Until
import androidx.test.uiautomator.Until.findObject
import mozilla.components.support.ktx.android.content.appName
import mozilla.components.browser.state.state.searchEngines
import org.hamcrest.CoreMatchers.allOf
import org.hamcrest.CoreMatchers.containsString
import org.hamcrest.CoreMatchers.instanceOf
import org.hamcrest.CoreMatchers.not
import org.hamcrest.Matchers
import org.junit.Assert
import org.mozilla.fenix.R
import org.mozilla.fenix.components.Search
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.helpers.TestAssetHelper
import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime
import org.mozilla.fenix.helpers.TestHelper.scrollToElementByText
Expand Down Expand Up @@ -579,10 +580,11 @@ private fun verifySearchEngineIcon(searchEngineIcon: Bitmap, searchEngineName: S
}

private fun getSearchEngine(searchEngineName: String) =
Search(appContext).searchEngineManager.getDefaultSearchEngine(appContext, searchEngineName)
appContext.components.core.store.state.search.searchEngines.find { it.name == searchEngineName }

private fun verifySearchEngineIcon(searchEngineName: String) {
val ddgSearchEngine = getSearchEngine(searchEngineName)
?: throw AssertionError("No search engine with name $searchEngineName")
verifySearchEngineIcon(ddgSearchEngine.icon, ddgSearchEngine.name)
}

Expand Down
26 changes: 14 additions & 12 deletions app/src/main/java/org/mozilla/fenix/HomeActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import mozilla.components.browser.search.SearchEngine
import mozilla.components.browser.state.search.SearchEngine
import mozilla.components.browser.state.selector.getNormalOrPrivateTabs
import mozilla.components.browser.state.state.SessionState
import mozilla.components.browser.state.state.WebExtensionState
Expand All @@ -46,6 +46,7 @@ import mozilla.components.concept.engine.EngineView
import mozilla.components.feature.contextmenu.DefaultSelectionActionDelegate
import mozilla.components.feature.privatemode.notification.PrivateNotificationFeature
import mozilla.components.feature.search.BrowserStoreSearchAdapter
import mozilla.components.feature.search.ext.legacy
import mozilla.components.service.fxa.sync.SyncReason
import mozilla.components.support.base.feature.UserInteractionHandler
import mozilla.components.support.ktx.android.arch.lifecycle.addObservers
Expand Down Expand Up @@ -139,7 +140,7 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {

private val externalSourceIntentProcessors by lazy {
listOf(
SpeechProcessingIntentProcessor(this, components.analytics.metrics),
SpeechProcessingIntentProcessor(this, components.core.store, components.analytics.metrics),
StartSearchIntentProcessor(components.analytics.metrics),
DeepLinkIntentProcessor(this, components.analytics.leanplumMetricsService),
OpenBrowserIntentProcessor(this, ::getIntentSessionId),
Expand Down Expand Up @@ -737,23 +738,24 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
}
} else components.useCases.sessionUseCases.loadUrl

val searchUseCase: (String) -> Unit = { searchTerms ->
// In situations where we want to perform a search but have no search engine (e.g. the user
// has removed all of them, or we couldn't load any) we will pass searchTermOrURL to Gecko
// and let it try to load whatever was entered.
if ((!forceSearch && searchTermOrURL.isUrl()) || engine == null) {
loadUrlUseCase.invoke(searchTermOrURL.toNormalizedUrl(), flags)
} else {
if (newTab) {
components.useCases.searchUseCases.newTabSearch
.invoke(
searchTerms,
searchTermOrURL,
SessionState.Source.USER_ENTERED,
true,
mode.isPrivate,
searchEngine = engine
searchEngine = engine.legacy()
)
} else components.useCases.searchUseCases.defaultSearch.invoke(searchTerms, engine)
}

if (!forceSearch && searchTermOrURL.isUrl()) {
loadUrlUseCase.invoke(searchTermOrURL.toNormalizedUrl(), flags)
} else {
searchUseCase.invoke(searchTermOrURL)
} else {
components.useCases.searchUseCases.defaultSearch.invoke(searchTermOrURL, engine.legacy())
}
}

if (components.core.engine.profiler?.isProfilerActive() == true) {
Expand Down
3 changes: 2 additions & 1 deletion app/src/main/java/org/mozilla/fenix/components/Analytics.kt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import org.mozilla.fenix.components.metrics.AdjustMetricsService
import org.mozilla.fenix.components.metrics.GleanMetricsService
import org.mozilla.fenix.components.metrics.LeanplumMetricsService
import org.mozilla.fenix.components.metrics.MetricController
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.perf.lazyMonitored
import org.mozilla.fenix.utils.Mockable
Expand Down Expand Up @@ -92,7 +93,7 @@ class Analytics(
val metrics: MetricController by lazyMonitored {
MetricController.create(
listOf(
GleanMetricsService(context),
GleanMetricsService(context, lazy { context.components.core.store }),
leanplumMetricsService,
AdjustMetricsService(context as Application)
),
Expand Down
2 changes: 0 additions & 2 deletions app/src/main/java/org/mozilla/fenix/components/Components.kt
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,12 @@ class Components(private val context: Context) {
}
val services by lazyMonitored { Services(context, backgroundServices.accountManager) }
val core by lazyMonitored { Core(context, analytics.crashReporter, strictMode) }
val search by lazyMonitored { Search(context) }
val useCases by lazyMonitored {
UseCases(
context,
core.engine,
core.sessionManager,
core.store,
search.searchEngineManager,
core.webAppShortcutManager,
core.topSitesStorage
)
Expand Down
22 changes: 21 additions & 1 deletion app/src/main/java/org/mozilla/fenix/components/Core.kt
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ import mozilla.components.feature.pwa.ManifestStorage
import mozilla.components.feature.pwa.WebAppShortcutManager
import mozilla.components.feature.readerview.ReaderViewMiddleware
import mozilla.components.feature.recentlyclosed.RecentlyClosedMiddleware
import mozilla.components.feature.search.middleware.SearchMiddleware
import mozilla.components.feature.search.region.RegionMiddleware
import mozilla.components.feature.session.HistoryDelegate
import mozilla.components.feature.top.sites.DefaultTopSitesStorage
import mozilla.components.feature.top.sites.PinnedSiteStorage
Expand All @@ -57,14 +59,18 @@ import mozilla.components.lib.dataprotect.generateEncryptionKey
import mozilla.components.service.digitalassetlinks.RelationChecker
import mozilla.components.service.digitalassetlinks.local.StatementApi
import mozilla.components.service.digitalassetlinks.local.StatementRelationChecker
import mozilla.components.service.location.LocationService
import mozilla.components.service.location.MozillaLocationService
import mozilla.components.service.sync.logins.SyncableLoginsStorage
import mozilla.components.support.locale.LocaleManager
import org.mozilla.fenix.AppRequestInterceptor
import org.mozilla.fenix.BuildConfig
import org.mozilla.fenix.Config
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.R
import org.mozilla.fenix.perf.StrictModeManager
import org.mozilla.fenix.TelemetryMiddleware
import org.mozilla.fenix.components.search.SearchMigration
import org.mozilla.fenix.downloads.DownloadService
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.settings
Expand Down Expand Up @@ -153,6 +159,14 @@ class Core(
SessionStorage(context, engine = engine)
}

private val locationService: LocationService by lazyMonitored {
if (Config.channel.isDebug || BuildConfig.MLS_TOKEN.isEmpty()) {
LocationService.default()
} else {
MozillaLocationService(context, client, BuildConfig.MLS_TOKEN)
}
}

/**
* The [BrowserStore] holds the global [BrowserState].
*/
Expand All @@ -169,7 +183,13 @@ class Core(
metrics
),
ThumbnailsMiddleware(thumbnailStorage),
UndoMiddleware(::lookupSessionManager, context.getUndoDelay())
UndoMiddleware(::lookupSessionManager, context.getUndoDelay()),
RegionMiddleware(context, locationService),
SearchMiddleware(
context,
additionalBundledSearchEngineIds = listOf("reddit", "youtube"),
migration = SearchMigration(context)
)
) + EngineMiddleware.create(engine, ::findSessionById)
).also {
it.dispatch(RecentlyClosedAction.InitializeRecentlyClosedState)
Expand Down
37 changes: 0 additions & 37 deletions app/src/main/java/org/mozilla/fenix/components/Search.kt

This file was deleted.

6 changes: 2 additions & 4 deletions app/src/main/java/org/mozilla/fenix/components/UseCases.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
package org.mozilla.fenix.components

import android.content.Context
import mozilla.components.browser.search.SearchEngineManager
import mozilla.components.browser.session.SessionManager
import mozilla.components.browser.state.store.BrowserStore
import mozilla.components.concept.engine.Engine
Expand All @@ -15,7 +14,7 @@ import mozilla.components.feature.downloads.DownloadsUseCases
import mozilla.components.feature.pwa.WebAppShortcutManager
import mozilla.components.feature.pwa.WebAppUseCases
import mozilla.components.feature.search.SearchUseCases
import mozilla.components.browser.search.ext.toDefaultSearchEngineProvider
import mozilla.components.feature.search.ext.toDefaultSearchEngineProvider
import mozilla.components.feature.session.SessionUseCases
import mozilla.components.feature.session.SettingsUseCases
import mozilla.components.feature.session.TrackingProtectionUseCases
Expand All @@ -36,7 +35,6 @@ class UseCases(
private val engine: Engine,
private val sessionManager: SessionManager,
private val store: BrowserStore,
private val searchEngineManager: SearchEngineManager,
private val shortcutManager: WebAppShortcutManager,
private val topSitesStorage: TopSitesStorage
) {
Expand All @@ -56,7 +54,7 @@ class UseCases(
val searchUseCases by lazyMonitored {
SearchUseCases(
store,
searchEngineManager.toDefaultSearchEngineProvider(context),
store.toDefaultSearchEngineProvider(),
sessionManager
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ package org.mozilla.fenix.components.metrics

import android.content.Context
import mozilla.components.browser.errorpages.ErrorType
import mozilla.components.browser.search.SearchEngine
import mozilla.components.browser.state.search.SearchEngine
import mozilla.components.feature.top.sites.TopSite
import org.mozilla.fenix.GleanMetrics.Addons
import org.mozilla.fenix.GleanMetrics.AppTheme
Expand Down Expand Up @@ -404,7 +404,7 @@ sealed class Event {
// https://github.com/mozilla-mobile/fenix/issues/1607
// Sanitize identifiers for custom search engines.
val identifier: String
get() = if (isCustom) "custom" else engine.identifier
get() = if (isCustom) "custom" else engine.id

val searchEngine: SearchEngine
get() = when (this) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
package org.mozilla.fenix.components.metrics

import android.content.Context
import mozilla.components.browser.state.store.BrowserStore
import mozilla.components.feature.search.ext.legacy
import mozilla.components.feature.search.ext.waitForSelectedOrDefaultSearchEngine
import mozilla.components.service.fxa.manager.SyncEnginesStorage
import mozilla.components.service.glean.Glean
import mozilla.components.service.glean.private.NoExtraKeys
Expand Down Expand Up @@ -682,6 +685,7 @@ private val Event.wrapper: EventWrapper<*>?

class GleanMetricsService(
private val context: Context,
private val store: Lazy<BrowserStore>,
private val browsersCache: BrowsersCache = BrowsersCache,
private val mozillaProductDetector: MozillaProductDetector = MozillaProductDetector
) : MetricsService {
Expand Down Expand Up @@ -756,20 +760,18 @@ class GleanMetricsService(
closeTabSetting.set(context.settings().getTabTimeoutPingString())
}

SearchDefaultEngine.apply {
val defaultEngine = context
.components
.search
.searchEngineManager
.defaultSearchEngine ?: return@apply
store.value.waitForSelectedOrDefaultSearchEngine { searchEngine ->
if (searchEngine != null) {
SearchDefaultEngine.apply {
code.set(searchEngine.id)
name.set(searchEngine.name)
submissionUrl.set(searchEngine.legacy().buildSearchUrl(""))
}
}

code.set(defaultEngine.identifier)
name.set(defaultEngine.name)
submissionUrl.set(defaultEngine.buildSearchUrl(""))
activationPing.checkAndSend()
installationPing.checkAndSend()
}

activationPing.checkAndSend()
installationPing.checkAndSend()
}

private fun setPreferenceMetrics() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,12 @@ import com.google.android.gms.common.GooglePlayServicesNotAvailableException
import com.google.android.gms.common.GooglePlayServicesRepairableException
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import mozilla.components.browser.search.SearchEngine
import mozilla.components.browser.state.search.SearchEngine
import mozilla.components.browser.state.state.selectedOrDefaultSearchEngine
import mozilla.components.browser.state.store.BrowserStore
import mozilla.components.support.base.log.logger.Logger
import org.mozilla.fenix.components.metrics.Event.PerformedSearch.SearchAccessPoint
import org.mozilla.fenix.components.searchengine.CustomSearchEngineStore
import org.mozilla.fenix.ext.searchEngineManager
import org.mozilla.fenix.ext.components
import java.io.IOException
import java.security.NoSuchAlgorithmException
import java.security.spec.InvalidKeySpecException
Expand All @@ -26,11 +27,11 @@ import javax.crypto.spec.PBEKeySpec
object MetricsUtils {
fun createSearchEvent(
engine: SearchEngine,
context: Context,
store: BrowserStore,
searchAccessPoint: SearchAccessPoint
): Event.PerformedSearch? {
val isShortcut = engine != context.searchEngineManager.defaultSearchEngine
val isCustom = CustomSearchEngineStore.isCustomSearchEngine(context, engine.identifier)
val isShortcut = engine != store.state.search.selectedOrDefaultSearchEngine
val isCustom = engine.type == SearchEngine.Type.CUSTOM

val engineSource =
if (isShortcut) Event.PerformedSearch.EngineSource.Shortcut(engine, isCustom)
Expand Down

0 comments on commit 2b759e9

Please sign in to comment.