Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add pixels #4902

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,9 @@ import com.duckduckgo.app.onboarding.store.UserStageStore
import com.duckduckgo.app.onboarding.ui.page.extendedonboarding.ExtendedOnboardingFeatureToggles
import com.duckduckgo.app.pixels.AppPixelName
import com.duckduckgo.app.pixels.AppPixelName.AUTOCOMPLETE_BANNER_SHOWN
import com.duckduckgo.app.pixels.AppPixelName.DUCK_PLAYER_SETTING_ALWAYS_DUCK_PLAYER
import com.duckduckgo.app.pixels.AppPixelName.DUCK_PLAYER_SETTING_ALWAYS_OVERLAY_YOUTUBE
import com.duckduckgo.app.pixels.AppPixelName.DUCK_PLAYER_SETTING_NEVER_OVERLAY_YOUTUBE
import com.duckduckgo.app.pixels.AppPixelName.ONBOARDING_SEARCH_CUSTOM
import com.duckduckgo.app.pixels.AppPixelName.ONBOARDING_VISIT_SITE_CUSTOM
import com.duckduckgo.app.pixels.remoteconfig.AndroidBrowserConfigFeature
Expand Down Expand Up @@ -645,7 +648,7 @@ class BrowserTabViewModelTest {
newTabPixels = { mockNewTabPixels },
httpErrorPixels = { mockHttpErrorPixels },
duckPlayer = mockDuckPlayer,
duckPlayerJSHelper = DuckPlayerJSHelper(mockDuckPlayer, mockAppBuildConfig),
duckPlayerJSHelper = DuckPlayerJSHelper(mockDuckPlayer, mockAppBuildConfig, mockPixel),
)

testee.loadData("abc", null, false, false)
Expand Down Expand Up @@ -4912,17 +4915,33 @@ class BrowserTabViewModelTest {
}

@Test
fun whenProcessJsCallbackMessageSetUserPreferencesFromDuckPlayerOverlayThenSendCommand() = runTest {
fun whenProcessJsCallbackMessageSetUserPreferencesDisabledFromDuckPlayerOverlayThenSendCommand() = runTest {
whenever(mockEnabledToggle.isEnabled()).thenReturn(true)
whenever(mockDuckPlayer.getUserPreferences()).thenReturn(UserPreferences(overlayInteracted = true, privatePlayerMode = AlwaysAsk))
testee.processJsCallbackMessage(
DUCK_PLAYER_FEATURE_NAME,
"setUserValues",
"id",
JSONObject("""{ overlayInteracted: "true", privatePlayerMode: {alwaysAsk: {} }}"""),
JSONObject("""{ overlayInteracted: "true", privatePlayerMode: {disabled: {} }}"""),
)
assertCommandIssued<Command.SendResponseToJs>()
verify(mockDuckPlayer).setUserPreferences(any(), any())
verify(mockPixel).fire(DUCK_PLAYER_SETTING_NEVER_OVERLAY_YOUTUBE)
}

@Test
fun whenProcessJsCallbackMessageSetUserPreferencesEnabledFromDuckPlayerOverlayThenSendCommand() = runTest {
whenever(mockEnabledToggle.isEnabled()).thenReturn(true)
whenever(mockDuckPlayer.getUserPreferences()).thenReturn(UserPreferences(overlayInteracted = true, privatePlayerMode = AlwaysAsk))
testee.processJsCallbackMessage(
DUCK_PLAYER_FEATURE_NAME,
"setUserValues",
"id",
JSONObject("""{ overlayInteracted: "true", privatePlayerMode: {enabled: {} }}"""),
)
assertCommandIssued<Command.SendResponseToJs>()
verify(mockDuckPlayer).setUserPreferences(any(), any())
verify(mockPixel).fire(DUCK_PLAYER_SETTING_ALWAYS_OVERLAY_YOUTUBE)
}

@Test
Expand All @@ -4933,10 +4952,11 @@ class BrowserTabViewModelTest {
DUCK_PLAYER_PAGE_FEATURE_NAME,
"setUserValues",
"id",
JSONObject("""{ overlayInteracted: "true", privatePlayerMode: {alwaysAsk: {} }}"""),
JSONObject("""{ overlayInteracted: "true", privatePlayerMode: {enabled: {} }}"""),
)
assertCommandIssued<Command.SendResponseToDuckPlayer>()
verify(mockDuckPlayer).setUserPreferences(true, "alwaysAsk")
verify(mockDuckPlayer).setUserPreferences(true, "enabled")
verify(mockPixel).fire(DUCK_PLAYER_SETTING_ALWAYS_DUCK_PLAYER)
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,17 @@

package com.duckduckgo.app.browser.duckplayer

import androidx.core.net.toUri
import com.duckduckgo.app.browser.commands.Command
import com.duckduckgo.app.browser.commands.Command.OpenDuckPlayerInfo
import com.duckduckgo.app.browser.commands.Command.OpenDuckPlayerSettings
import com.duckduckgo.app.browser.commands.Command.SendResponseToDuckPlayer
import com.duckduckgo.app.browser.commands.Command.SendResponseToJs
import com.duckduckgo.app.browser.commands.NavigationCommand.Navigate
import com.duckduckgo.app.pixels.AppPixelName.DUCK_PLAYER_SETTING_ALWAYS_DUCK_PLAYER
import com.duckduckgo.app.pixels.AppPixelName.DUCK_PLAYER_SETTING_ALWAYS_OVERLAY_YOUTUBE
import com.duckduckgo.app.pixels.AppPixelName.DUCK_PLAYER_SETTING_NEVER_OVERLAY_YOUTUBE
import com.duckduckgo.app.statistics.pixels.Pixel
import com.duckduckgo.appbuildconfig.api.AppBuildConfig
import com.duckduckgo.duckplayer.api.DuckPlayer
import com.duckduckgo.js.messaging.api.JsCallbackData
Expand All @@ -37,6 +42,7 @@ private const val PRIVATE_PLAYER_MODE = "privatePlayerMode"
class DuckPlayerJSHelper @Inject constructor(
private val duckPlayer: DuckPlayer,
private val appBuildConfig: AppBuildConfig,
private val pixel: Pixel,
) {
private suspend fun getUserPreferences(featureName: String, method: String, id: String): JsCallbackData {
val userValues = duckPlayer.getUserPreferences()
Expand Down Expand Up @@ -126,10 +132,20 @@ class DuckPlayerJSHelper @Inject constructor(
setUserPreferences(data)
return when (featureName) {
DUCK_PLAYER_FEATURE_NAME -> {
SendResponseToJs(getUserPreferences(featureName, method, id))
SendResponseToJs(getUserPreferences(featureName, method, id)).also {
if (data.getJSONObject(PRIVATE_PLAYER_MODE).keys().next() == "enabled") {
pixel.fire(DUCK_PLAYER_SETTING_ALWAYS_OVERLAY_YOUTUBE)
} else if (data.getJSONObject(PRIVATE_PLAYER_MODE).keys().next() == "disabled") {
pixel.fire(DUCK_PLAYER_SETTING_NEVER_OVERLAY_YOUTUBE)
}
}
}
DUCK_PLAYER_PAGE_FEATURE_NAME -> {
SendResponseToDuckPlayer(getUserPreferences(featureName, method, id))
SendResponseToDuckPlayer(getUserPreferences(featureName, method, id)).also {
if (data.getJSONObject(PRIVATE_PLAYER_MODE).keys().next() == "enabled") {
pixel.fire(DUCK_PLAYER_SETTING_ALWAYS_DUCK_PLAYER)
}
}
} else -> {
null
}
Expand All @@ -142,7 +158,7 @@ class DuckPlayerJSHelper @Inject constructor(
}
"openDuckPlayer" -> {
return data?.getString("href")?.let {
Navigate(it, mapOf())
Navigate(it.toUri().buildUpon().appendQueryParameter("origin", "overlay").build().toString(), mapOf())
}
}
"initialSetup" -> {
Expand Down
4 changes: 4 additions & 0 deletions app/src/main/java/com/duckduckgo/app/pixels/AppPixelName.kt
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,10 @@ enum class AppPixelName(override val pixelName: String) : Pixel.PixelName {
TAB_MANAGER_LIST_VIEW_BUTTON_CLICKED("m_tab_manager_list_view_button_clicked"),
TAB_MANAGER_VIEW_MODE_TOGGLED_DAILY("m_tab_manager_view_mode_toggled_daily"),

DUCK_PLAYER_SETTING_ALWAYS_OVERLAY_YOUTUBE("duck-player_setting_always_overlay_youtube"),
DUCK_PLAYER_SETTING_NEVER_OVERLAY_YOUTUBE("duck-player_setting_never_overlay_youtube"),
DUCK_PLAYER_SETTING_ALWAYS_DUCK_PLAYER("duck-player_setting_always_duck-player"),

ADD_BOOKMARK_CONFIRM_EDITED("m_add_bookmark_confirm_edit"),

REFERRAL_INSTALL_UTM_CAMPAIGN("m_android_install"),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
package com.duckduckgo.duckplayer.impl

import app.cash.turbine.test
import com.duckduckgo.app.statistics.pixels.Pixel
import com.duckduckgo.common.test.CoroutineTestRule
import com.duckduckgo.duckplayer.api.DuckPlayer
import com.duckduckgo.duckplayer.api.DuckPlayer.UserPreferences
import com.duckduckgo.duckplayer.api.PrivatePlayerMode.AlwaysAsk
import com.duckduckgo.duckplayer.api.PrivatePlayerMode.Disabled
import com.duckduckgo.duckplayer.api.PrivatePlayerMode.Enabled
import com.duckduckgo.duckplayer.impl.DuckPlayerPixelName.DUCK_PLAYER_SETTINGS_ALWAYS_SETTINGS
import com.duckduckgo.duckplayer.impl.DuckPlayerPixelName.DUCK_PLAYER_SETTINGS_BACK_TO_DEFAULT
import com.duckduckgo.duckplayer.impl.DuckPlayerPixelName.DUCK_PLAYER_SETTINGS_NEVER_SETTINGS
import com.duckduckgo.duckplayer.impl.DuckPlayerSettingsViewModel.Command.OpenPlayerModeSelector
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.flowOf
Expand All @@ -27,13 +32,14 @@ class DuckPlayerSettingsViewModelTest {

private val duckPlayer: DuckPlayer = mock()
private val duckPlayerFeatureRepository: DuckPlayerFeatureRepository = mock()
private val pixel: Pixel = mock()
private lateinit var viewModel: DuckPlayerSettingsViewModel

@Before
fun setUp() {
runTest {
whenever(duckPlayer.getUserPreferences()).thenReturn(UserPreferences(overlayInteracted = true, privatePlayerMode = AlwaysAsk))
viewModel = DuckPlayerSettingsViewModel(duckPlayer, duckPlayerFeatureRepository)
viewModel = DuckPlayerSettingsViewModel(duckPlayer, duckPlayerFeatureRepository, pixel)
}
}

Expand All @@ -51,12 +57,29 @@ class DuckPlayerSettingsViewModelTest {
viewModel.onPlayerModeSelected(Disabled)

verify(duckPlayer).setUserPreferences(overlayInteracted = false, privatePlayerMode = Disabled.value)
verify(pixel).fire(DUCK_PLAYER_SETTINGS_NEVER_SETTINGS)
}

@Test
fun whenPrivatePlayerModeIsSelectedToAlwaysAskThenUpdateUserPreferences() = runTest {
viewModel.onPlayerModeSelected(AlwaysAsk)

verify(duckPlayer).setUserPreferences(overlayInteracted = false, privatePlayerMode = AlwaysAsk.value)
verify(pixel).fire(DUCK_PLAYER_SETTINGS_BACK_TO_DEFAULT)
}

@Test
fun whenPrivatePlayerModeIsSelectedToAlwaysThenUpdateUserPreferences() = runTest {
viewModel.onPlayerModeSelected(Enabled)

verify(duckPlayer).setUserPreferences(overlayInteracted = false, privatePlayerMode = Enabled.value)
verify(pixel).fire(DUCK_PLAYER_SETTINGS_ALWAYS_SETTINGS)
}

@Test
fun whenViewModelIsCreatedAndPrivatePlayerModeIsDisabledThenEmitDisabled() = runTest {
whenever(duckPlayer.observeUserPreferences()).thenReturn(flowOf(UserPreferences(overlayInteracted = true, privatePlayerMode = Disabled)))
viewModel = DuckPlayerSettingsViewModel(duckPlayer, duckPlayerFeatureRepository)
viewModel = DuckPlayerSettingsViewModel(duckPlayer, duckPlayerFeatureRepository, pixel)

viewModel.viewState.test {
assertEquals(Disabled, awaitItem().privatePlayerMode)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 DuckDuckGo
* Copyright (c) 2024 DuckDuckGo
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -19,5 +19,15 @@ package com.duckduckgo.duckplayer.impl
import com.duckduckgo.app.statistics.pixels.Pixel

enum class DuckPlayerPixelName(override val pixelName: String) : Pixel.PixelName {
SETTINGS_DUCK_PLAYER_PRESSED("ms_duck_player_setting_pressed"),
DUCK_PLAYER_OVERLAY_YOUTUBE_IMPRESSIONS("duck-player_overlay_youtube_impressions"),
DUCK_PLAYER_VIEW_FROM_YOUTUBE_MAIN_OVERLAY("duck-player_view-from_youtube_main-overlay"),
DUCK_PLAYER_OVERLAY_YOUTUBE_WATCH_HERE("duck-player_overlay_youtube_watch_here"),
DUCK_PLAYER_WATCH_ON_YOUTUBE("duck-player_watch_on_youtube"),
DUCK_PLAYER_DAILY_UNIQUE_VIEW("duck-player_daily-unique-view"),
DUCK_PLAYER_VIEW_FROM_YOUTUBE_AUTOMATIC("duck-player_view-from_youtube_automatic"),
DUCK_PLAYER_VIEW_FROM_OTHER("duck-player_view-from_other"),
DUCK_PLAYER_SETTINGS_ALWAYS_SETTINGS("duck-player_setting_always_settings"),
DUCK_PLAYER_SETTINGS_BACK_TO_DEFAULT("duck-player_setting_back-to-default"),
DUCK_PLAYER_SETTINGS_NEVER_SETTINGS("duck-player_setting_never_settings"),
DUCK_PLAYER_SETTINGS_PRESSED("duck_player_setting_pressed"),
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import com.duckduckgo.app.statistics.pixels.Pixel
import com.duckduckgo.common.ui.view.listitem.OneLineListItem
import com.duckduckgo.di.scopes.ActivityScope
import com.duckduckgo.duckplayer.api.DuckPlayerSettingsNoParams
import com.duckduckgo.duckplayer.impl.DuckPlayerPixelName.SETTINGS_DUCK_PLAYER_PRESSED
import com.duckduckgo.duckplayer.impl.DuckPlayerPixelName.DUCK_PLAYER_SETTINGS_PRESSED
import com.duckduckgo.navigation.api.GlobalActivityStarter
import com.duckduckgo.settings.api.DuckPlayerSettingsPlugin
import com.squareup.anvil.annotations.ContributesMultibinding
Expand All @@ -39,7 +39,7 @@ class DuckPlayerSettingsTitle @Inject constructor(
return OneLineListItem(context).apply {
setPrimaryText(context.getString(R.string.duck_player_setting_title))
setOnClickListener {
pixel.fire(SETTINGS_DUCK_PLAYER_PRESSED)
pixel.fire(DUCK_PLAYER_SETTINGS_PRESSED)
globalActivityStarter.start(this.context, DuckPlayerSettingsNoParams, null)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,16 @@ package com.duckduckgo.duckplayer.impl
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.duckduckgo.anvil.annotations.ContributesViewModel
import com.duckduckgo.app.statistics.pixels.Pixel
import com.duckduckgo.di.scopes.ActivityScope
import com.duckduckgo.duckplayer.api.DuckPlayer
import com.duckduckgo.duckplayer.api.DuckPlayer.DuckPlayerState.DISABLED_WIH_HELP_LINK
import com.duckduckgo.duckplayer.api.PrivatePlayerMode
import com.duckduckgo.duckplayer.api.PrivatePlayerMode.AlwaysAsk
import com.duckduckgo.duckplayer.api.PrivatePlayerMode.Disabled
import com.duckduckgo.duckplayer.impl.DuckPlayerPixelName.DUCK_PLAYER_SETTINGS_ALWAYS_SETTINGS
import com.duckduckgo.duckplayer.impl.DuckPlayerPixelName.DUCK_PLAYER_SETTINGS_BACK_TO_DEFAULT
import com.duckduckgo.duckplayer.impl.DuckPlayerPixelName.DUCK_PLAYER_SETTINGS_NEVER_SETTINGS
import com.duckduckgo.duckplayer.impl.DuckPlayerSettingsViewModel.Command.OpenLearnMore
import com.duckduckgo.duckplayer.impl.DuckPlayerSettingsViewModel.Command.OpenPlayerModeSelector
import com.duckduckgo.duckplayer.impl.DuckPlayerSettingsViewModel.ViewState.DisabledWithHelpLink
Expand All @@ -43,6 +48,7 @@ import kotlinx.coroutines.runBlocking
class DuckPlayerSettingsViewModel @Inject constructor(
private val duckPlayer: DuckPlayer,
private val duckPlayerFeatureRepository: DuckPlayerFeatureRepository,
private val pixel: Pixel,
) : ViewModel() {

private val commandChannel = Channel<Command>(capacity = 1, onBufferOverflow = DROP_OLDEST)
Expand Down Expand Up @@ -81,7 +87,14 @@ class DuckPlayerSettingsViewModel @Inject constructor(

fun onPlayerModeSelected(selectedPlayerMode: PrivatePlayerMode) {
viewModelScope.launch {
duckPlayer.setUserPreferences(overlayInteracted = false, privatePlayerMode = selectedPlayerMode.value)
duckPlayer.setUserPreferences(overlayInteracted = false, privatePlayerMode = selectedPlayerMode.value).also {
val pixelName = when (selectedPlayerMode) {
is PrivatePlayerMode.Enabled -> { DUCK_PLAYER_SETTINGS_ALWAYS_SETTINGS }
is AlwaysAsk -> { DUCK_PLAYER_SETTINGS_BACK_TO_DEFAULT }
is Disabled -> { DUCK_PLAYER_SETTINGS_NEVER_SETTINGS }
}
pixel.fire(pixelName)
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import android.webkit.WebView
import androidx.core.net.toUri
import androidx.fragment.app.FragmentManager
import com.duckduckgo.app.statistics.pixels.Pixel
import com.duckduckgo.app.statistics.pixels.Pixel.PixelType.DAILY
import com.duckduckgo.common.utils.DispatcherProvider
import com.duckduckgo.common.utils.UrlScheme.Companion.duck
import com.duckduckgo.common.utils.UrlScheme.Companion.https
Expand All @@ -38,6 +39,13 @@ import com.duckduckgo.duckplayer.api.DuckPlayer.UserPreferences
import com.duckduckgo.duckplayer.api.PrivatePlayerMode.AlwaysAsk
import com.duckduckgo.duckplayer.api.PrivatePlayerMode.Disabled
import com.duckduckgo.duckplayer.api.PrivatePlayerMode.Enabled
import com.duckduckgo.duckplayer.impl.DuckPlayerPixelName.DUCK_PLAYER_DAILY_UNIQUE_VIEW
import com.duckduckgo.duckplayer.impl.DuckPlayerPixelName.DUCK_PLAYER_OVERLAY_YOUTUBE_IMPRESSIONS
import com.duckduckgo.duckplayer.impl.DuckPlayerPixelName.DUCK_PLAYER_OVERLAY_YOUTUBE_WATCH_HERE
import com.duckduckgo.duckplayer.impl.DuckPlayerPixelName.DUCK_PLAYER_VIEW_FROM_OTHER
import com.duckduckgo.duckplayer.impl.DuckPlayerPixelName.DUCK_PLAYER_VIEW_FROM_YOUTUBE_AUTOMATIC
import com.duckduckgo.duckplayer.impl.DuckPlayerPixelName.DUCK_PLAYER_VIEW_FROM_YOUTUBE_MAIN_OVERLAY
import com.duckduckgo.duckplayer.impl.DuckPlayerPixelName.DUCK_PLAYER_WATCH_ON_YOUTUBE
import com.duckduckgo.duckplayer.impl.ui.DuckPlayerPrimeBottomSheet
import com.duckduckgo.duckplayer.impl.ui.DuckPlayerPrimeDialogFragment
import com.squareup.anvil.annotations.ContributesBinding
Expand Down Expand Up @@ -128,8 +136,12 @@ class RealDuckPlayer @Inject constructor(
pixelName: String,
pixelData: Map<String, String>,
) {
val androidPixelName = "m_${pixelName.replace('.', '_')}"
pixel.fire(androidPixelName, pixelData)
when (pixelName) {
"overlay" -> pixel.fire(DUCK_PLAYER_OVERLAY_YOUTUBE_IMPRESSIONS, parameters = pixelData)
"play.use" -> pixel.fire(DUCK_PLAYER_VIEW_FROM_YOUTUBE_MAIN_OVERLAY, parameters = pixelData)
"play.do_not_use" -> pixel.fire(DUCK_PLAYER_OVERLAY_YOUTUBE_WATCH_HERE, parameters = pixelData)
else -> {}
}
}

private suspend fun createYoutubeNoCookieFromDuckPlayer(uri: Uri): String? {
Expand Down Expand Up @@ -157,6 +169,7 @@ class RealDuckPlayer @Inject constructor(
if (getUserPreferences().privatePlayerMode == AlwaysAsk) {
shouldHideOverlay = true
}
pixel.fire(DUCK_PLAYER_WATCH_ON_YOUTUBE)
}
private fun isDuckPlayerUri(uri: Uri): Boolean {
if (uri.normalizeScheme()?.scheme != duck) return false
Expand Down Expand Up @@ -207,7 +220,7 @@ class RealDuckPlayer @Inject constructor(

private suspend fun createDuckPlayerUriFromYoutube(uri: Uri): String {
val videoIdQueryParam = duckPlayerFeatureRepository.getVideoIDQueryParam()
return "$DUCK_PLAYER_URL_BASE${uri.getQueryParameter(videoIdQueryParam)}"
return "$DUCK_PLAYER_URL_BASE${uri.getQueryParameter(videoIdQueryParam)}?origin=auto"
}

override suspend fun intercept(
Expand Down Expand Up @@ -242,7 +255,9 @@ class RealDuckPlayer @Inject constructor(
}
} else {
val inputStream: InputStream = webView.context.assets.open(DUCK_PLAYER_ASSETS_INDEX_PATH)
return WebResourceResponse("text/html", "UTF-8", inputStream)
return WebResourceResponse("text/html", "UTF-8", inputStream).also {
pixel.fire(DUCK_PLAYER_DAILY_UNIQUE_VIEW, type = DAILY)
}
}
}

Expand Down Expand Up @@ -271,6 +286,7 @@ class RealDuckPlayer @Inject constructor(
withContext(dispatchers.main()) {
webView.loadUrl(createDuckPlayerUriFromYoutube(url))
}
pixel.fire(DUCK_PLAYER_VIEW_FROM_YOUTUBE_AUTOMATIC)
return WebResourceResponse(null, null, null)
}
return null
Expand All @@ -292,6 +308,9 @@ class RealDuckPlayer @Inject constructor(
withContext(dispatchers.main()) {
webView.loadUrl(youtubeUrl)
}
if (url.getQueryParameter("origin") != "overlay" && url.getQueryParameter("origin") != "auto") {
pixel.fire(DUCK_PLAYER_VIEW_FROM_OTHER)
}
}
}
return WebResourceResponse(null, null, null)
Expand Down
Loading
Loading