Skip to content

Commit 49789e6

Browse files
committed
Support subscriptions by replying to ping message
1 parent ad552df commit 49789e6

File tree

6 files changed

+85
-5
lines changed

6 files changed

+85
-5
lines changed

app/src/main/java/com/duckduckgo/app/browser/BrowserTabFragment.kt

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1204,7 +1204,8 @@ class BrowserTabFragment :
12041204
private fun onOmnibarCustomTabPrivacyDashboardPressed() {
12051205
val params = PrivacyDashboardPrimaryScreen(tabId)
12061206
val intent = globalActivityStarter.startIntent(requireContext(), params)
1207-
contentScopeScripts.sendSubscriptionEvent(createBreakageReportingEventData())
1207+
adsJsContentScopeScripts.postMessage(createBreakageReportingEventData())
1208+
// contentScopeScripts.sendSubscriptionEvent(createBreakageReportingEventData())
12081209
intent?.let { activityResultPrivacyDashboard.launch(intent) }
12091210
pixel.fire(CustomTabPixelNames.CUSTOM_TABS_PRIVACY_DASHBOARD_OPENED)
12101211
}
@@ -1216,12 +1217,14 @@ class BrowserTabFragment :
12161217
}
12171218

12181219
private fun onBrowserMenuButtonPressed() {
1219-
contentScopeScripts.sendSubscriptionEvent(createBreakageReportingEventData())
1220+
adsJsContentScopeScripts.postMessage(createBreakageReportingEventData())
1221+
// contentScopeScripts.sendSubscriptionEvent(createBreakageReportingEventData())
12201222
viewModel.onBrowserMenuClicked(isCustomTab = isActiveCustomTab())
12211223
}
12221224

12231225
private fun onOmnibarPrivacyShieldButtonPressed() {
1224-
contentScopeScripts.sendSubscriptionEvent(createBreakageReportingEventData())
1226+
adsJsContentScopeScripts.postMessage(createBreakageReportingEventData())
1227+
// contentScopeScripts.sendSubscriptionEvent(createBreakageReportingEventData())
12251228
viewModel.onOmnibarPrivacyShieldButtonPressed()
12261229
launchPrivacyDashboard(toggle = false)
12271230
}

app/src/main/java/com/duckduckgo/app/browser/BrowserTabViewModel.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3647,6 +3647,9 @@ class BrowserTabViewModel @Inject constructor(
36473647
"webShare" -> if (id != null && data != null) {
36483648
adsjsWebShare(featureName, method, id, data, onResponse)
36493649
}
3650+
"breakageReportResult" -> if (data != null) {
3651+
breakageReportResult(data)
3652+
}
36503653
}
36513654
}
36523655

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*
2+
* Copyright (c) 2024 DuckDuckGo
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.duckduckgo.breakagereporting.impl
18+
19+
import com.duckduckgo.contentscopescripts.api.AdsjsContentScopeJsMessageHandlersPlugin
20+
import com.duckduckgo.di.scopes.ActivityScope
21+
import com.duckduckgo.js.messaging.api.AdsjsJsMessageCallback
22+
import com.duckduckgo.js.messaging.api.AdsjsMessageHandler
23+
import com.duckduckgo.js.messaging.api.JsMessage
24+
import com.squareup.anvil.annotations.ContributesMultibinding
25+
import javax.inject.Inject
26+
import org.json.JSONObject
27+
28+
@ContributesMultibinding(ActivityScope::class)
29+
class AdsjsBreakageContentScopeJsMessageHandler @Inject constructor() : AdsjsContentScopeJsMessageHandlersPlugin {
30+
31+
override fun getJsMessageHandler(): AdsjsMessageHandler = object : AdsjsMessageHandler {
32+
33+
override fun process(
34+
jsMessage: JsMessage,
35+
jsMessageCallback: AdsjsJsMessageCallback?,
36+
onResponse: (JSONObject) -> Unit,
37+
) {
38+
jsMessageCallback?.process(featureName, jsMessage.method, jsMessage.id, jsMessage.params, onResponse)
39+
}
40+
41+
override val featureName: String = "breakageReporting"
42+
override val methods: List<String> = listOf("breakageReportResult")
43+
}
44+
}

content-scope-scripts/content-scope-scripts-impl/src/main/java/com/duckduckgo/contentscopescripts/impl/messaging/AdsjsContentScopeMessaging.kt

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ import com.duckduckgo.js.messaging.api.AdsjsJsMessageCallback
3131
import com.duckduckgo.js.messaging.api.AdsjsMessaging
3232
import com.duckduckgo.js.messaging.api.JsCallbackData
3333
import com.duckduckgo.js.messaging.api.JsMessage
34+
import com.duckduckgo.js.messaging.api.SubscriptionEvent
35+
import com.duckduckgo.js.messaging.api.SubscriptionEventData
3436
import com.squareup.anvil.annotations.ContributesBinding
3537
import com.squareup.moshi.Moshi
3638
import javax.inject.Inject
@@ -59,6 +61,8 @@ class AdsjsContentScopeMessaging @Inject constructor(
5961
override val context: String = "contentScopeScripts"
6062
override val allowedDomains: Set<String> = setOf("*")
6163

64+
private var globalReplyProxy: JavaScriptReplyProxy? = null
65+
6266
private fun process(
6367
message: String,
6468
jsMessageCallback: AdsjsJsMessageCallback,
@@ -71,12 +75,16 @@ class AdsjsContentScopeMessaging @Inject constructor(
7175
jsMessage?.let {
7276
if (context == jsMessage.context) {
7377
// Process global handlers first (always processed regardless of feature handlers)
78+
79+
if (jsMessage.featureName == "messaging" || jsMessage.method == "initialPing") {
80+
globalReplyProxy = replyProxy
81+
}
82+
7483
globalHandlers.getPlugins()
7584
.map { it.getGlobalJsMessageHandler() }
7685
.filter { it.method == jsMessage.method }
7786
.forEach { handler ->
78-
handler.process(jsMessage, jsMessageCallback) {
79-
}
87+
handler.process(jsMessage, jsMessageCallback) { }
8088
}
8189

8290
// Process with feature handlers
@@ -159,4 +167,20 @@ class AdsjsContentScopeMessaging @Inject constructor(
159167
}
160168
}
161169
}
170+
171+
@SuppressLint("RequiresFeature")
172+
override fun postMessage(subscriptionEventData: SubscriptionEventData) {
173+
runCatching {
174+
val subscriptionEvent = SubscriptionEvent(
175+
context = context,
176+
featureName = subscriptionEventData.featureName,
177+
subscriptionName = subscriptionEventData.subscriptionName,
178+
params = subscriptionEventData.params,
179+
).let {
180+
moshi.adapter(SubscriptionEvent::class.java).toJson(it)
181+
}
182+
183+
globalReplyProxy?.postMessage(subscriptionEvent)
184+
}
185+
}
162186
}

js-messaging/js-messaging-api/src/main/java/com/duckduckgo/js/messaging/api/AdsjsMessaging.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ interface AdsjsMessaging {
3030
)
3131
suspend fun unregister(webView: WebView)
3232

33+
fun postMessage(subscriptionEventData: SubscriptionEventData)
34+
3335
/**
3436
* Context name
3537
*/

js-messaging/js-messaging-impl/src/main/java/com/duckduckgo/js/messaging/impl/RealJsMessageHelper.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import dagger.SingleInstanceIn
3333
import javax.inject.Inject
3434
import kotlinx.coroutines.CoroutineScope
3535
import kotlinx.coroutines.launch
36+
import logcat.logcat
3637

3738
@SingleInstanceIn(AppScope::class)
3839
@ContributesBinding(AppScope::class)
@@ -47,6 +48,9 @@ class RealJsMessageHelper @Inject constructor(
4748
val jsonAdapter: JsonAdapter<SubscriptionEvent> = moshi.adapter(SubscriptionEvent::class.java)
4849
val message = jsonAdapter.toJson(subscriptionEvent).toString()
4950
val response = buildJsResponse(message, callbackName, secret)
51+
52+
logcat("Cris") { "$response" }
53+
5054
sendResponse(response, webView)
5155
}
5256

0 commit comments

Comments
 (0)