diff --git a/duckplayer/duckplayer-impl/src/main/java/com/duckduckgo/duckplayer/impl/RealDuckPlayer.kt b/duckplayer/duckplayer-impl/src/main/java/com/duckduckgo/duckplayer/impl/RealDuckPlayer.kt index b3f0dd11296b..f9f65d4e9f6e 100644 --- a/duckplayer/duckplayer-impl/src/main/java/com/duckduckgo/duckplayer/impl/RealDuckPlayer.kt +++ b/duckplayer/duckplayer-impl/src/main/java/com/duckduckgo/duckplayer/impl/RealDuckPlayer.kt @@ -274,20 +274,30 @@ class RealDuckPlayer @Inject constructor( url: Uri, webView: WebView, ): WebResourceResponse? { - val referer = duckPlayerFeatureRepository.getYouTubeReferrerHeaders() - .firstOrNull { referrer -> request.requestHeaders[referrer] != null } - ?.let { referrer -> url.getQueryParameter(referrer) } + val referer = request.requestHeaders.keys.firstOrNull { it in duckPlayerFeatureRepository.getYouTubeReferrerHeaders() } + ?.let { url.getQueryParameter(it) } val previousUrl = duckPlayerFeatureRepository.getYouTubeReferrerQueryParams() - .firstOrNull { referrer -> url.getQueryParameter(referrer) != null } - ?.let { referrer -> url.getQueryParameter(referrer) } + .firstOrNull { url.getQueryParameter(it) != null } + ?.let { url.getQueryParameter(it) } + val currentUrl = withContext(dispatchers.main()) { webView.url } + val videoIdQueryParam = duckPlayerFeatureRepository.getVideoIDQueryParam() - if ((referer != null && isSimulatedYoutubeNoCookie(referer.toUri())) || - (previousUrl != null && isSimulatedYoutubeNoCookie(previousUrl)) + val requestedVideoId = url.getQueryParameter(videoIdQueryParam) + + val isSimulated: suspend (String?) -> Boolean = { uri -> + uri?.let { isSimulatedYoutubeNoCookie(it.toUri()) } == true + } + + val isMatchingVideoId: (String?) -> Boolean = { uri -> + uri?.toUri()?.getQueryParameter(DUCK_PLAYER_VIDEO_ID_QUERY_PARAM) == requestedVideoId + } + + if (isSimulated(referer) && isMatchingVideoId(referer) || + isSimulated(previousUrl) && isMatchingVideoId(previousUrl) || + isSimulated(currentUrl) && isMatchingVideoId(currentUrl) ) { withContext(dispatchers.main()) { - url.getQueryParameter(videoIdQueryParam)?.let { - webView.loadUrl("$DUCK_PLAYER_URL_BASE$DUCK_PLAYER_OPEN_IN_YOUTUBE_PATH?$videoIdQueryParam=$it") - } + webView.loadUrl("$DUCK_PLAYER_URL_BASE$DUCK_PLAYER_OPEN_IN_YOUTUBE_PATH?$videoIdQueryParam=$requestedVideoId") } return WebResourceResponse(null, null, null) } else if (shouldNavigateToDuckPlayer()) { diff --git a/duckplayer/duckplayer-impl/src/test/kotlin/com/duckduckgo/duckplayer/impl/RealDuckPlayerTest.kt b/duckplayer/duckplayer-impl/src/test/kotlin/com/duckduckgo/duckplayer/impl/RealDuckPlayerTest.kt index 8841a2039143..193e763b29e1 100644 --- a/duckplayer/duckplayer-impl/src/test/kotlin/com/duckduckgo/duckplayer/impl/RealDuckPlayerTest.kt +++ b/duckplayer/duckplayer-impl/src/test/kotlin/com/duckduckgo/duckplayer/impl/RealDuckPlayerTest.kt @@ -619,6 +619,36 @@ class RealDuckPlayerTest { assertNotNull(result) } + @Test + fun whenUriIsYoutubeWatchUrlAndPreviousUrlIsDuckPlayer_interceptOpensInYouTube() = runTest { + val request: WebResourceRequest = mock() + val url: Uri = Uri.parse("https://www.youtube.com/watch?v=12345") + val webView: WebView = mock() + whenever(mockDuckPlayerFeatureRepository.getUserPreferences()).thenReturn(UserPreferences(true, Enabled)) + whenever(webView.url).thenReturn("https://www.youtube-nocookie.com?videoID=12345") + + val result = testee.intercept(request, url, webView) + + verify(webView).loadUrl("duck://player/openInYoutube?v=12345") + verify(mockPixel, never()).fire(DUCK_PLAYER_VIEW_FROM_YOUTUBE_AUTOMATIC) + assertNotNull(result) + } + + @Test + fun whenUriIsYoutubeWatchUrlAndPreviousUrlIsDuckPlayerWithDifferentId_interceptOpensDuckPlayer() = runTest { + val request: WebResourceRequest = mock() + val url: Uri = Uri.parse("https://www.youtube.com/watch?v=123456") + val webView: WebView = mock() + whenever(mockDuckPlayerFeatureRepository.getUserPreferences()).thenReturn(UserPreferences(true, Enabled)) + whenever(webView.url).thenReturn("https://www.youtube-nocookie.com?videoID=12345") + + val result = testee.intercept(request, url, webView) + + verify(webView).loadUrl("duck://player/123456?origin=auto") + verify(mockPixel).fire(DUCK_PLAYER_VIEW_FROM_YOUTUBE_AUTOMATIC) + assertNotNull(result) + } + @Test fun whenUriIsYoutubeWatchUrlAndSettingsAlwaysAsk_interceptProcessesYoutubeWatchUri() = runTest { val request: WebResourceRequest = mock()