Skip to content

Commit fe3469b

Browse files
committed
Add handler for nativeDuckAiSettingChanged to sync Duck.ai setting changes with SERP
1 parent 32493b0 commit fe3469b

File tree

2 files changed

+132
-0
lines changed

2 files changed

+132
-0
lines changed
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
* Copyright (c) 2025 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.duckchat.impl.messaging
18+
19+
import com.duckduckgo.app.di.AppCoroutineScope
20+
import com.duckduckgo.common.utils.AppUrl
21+
import com.duckduckgo.common.utils.DispatcherProvider
22+
import com.duckduckgo.contentscopescripts.api.ContentScopeJsMessageHandlersPlugin
23+
import com.duckduckgo.di.scopes.AppScope
24+
import com.duckduckgo.duckchat.impl.DuckChatInternal
25+
import com.duckduckgo.js.messaging.api.JsMessage
26+
import com.duckduckgo.js.messaging.api.JsMessageCallback
27+
import com.duckduckgo.js.messaging.api.JsMessageHandler
28+
import com.duckduckgo.js.messaging.api.JsMessaging
29+
import com.duckduckgo.settings.api.SettingsPageFeature
30+
import com.squareup.anvil.annotations.ContributesMultibinding
31+
import kotlinx.coroutines.CoroutineScope
32+
import kotlinx.coroutines.launch
33+
import logcat.logcat
34+
import javax.inject.Inject
35+
36+
/**
37+
* Handles subscription to Duck.ai setting changes to notify SERP when the native setting changes.
38+
*
39+
* Purpose: When a user changes the Duck.ai setting in native Android settings,
40+
* this handler pushes the update to any active SERP pages so they can update their UI.
41+
*/
42+
@ContributesMultibinding(AppScope::class)
43+
class NativeDuckAiSettingChangedHandler @Inject constructor(
44+
duckChatInternal: DuckChatInternal,
45+
private val dispatcherProvider: DispatcherProvider,
46+
@AppCoroutineScope private val appCoroutineScope: CoroutineScope,
47+
private val settingsPageFeature: SettingsPageFeature,
48+
) : ContentScopeJsMessageHandlersPlugin {
49+
50+
override fun getJsMessageHandler(): JsMessageHandler =
51+
object : JsMessageHandler {
52+
53+
override fun process(
54+
jsMessage: JsMessage,
55+
jsMessaging: JsMessaging,
56+
jsMessageCallback: JsMessageCallback?,
57+
) {
58+
appCoroutineScope.launch(dispatcherProvider.io()) {
59+
if (settingsPageFeature.serpSettingsSync().isEnabled()) {
60+
logcat { "SERP-SETTINGS: Subscribing SERP page to Duck.ai setting changes" }
61+
62+
// TODO observe and send back updates
63+
}
64+
}
65+
}
66+
67+
override val allowedDomains: List<String> = listOf(AppUrl.Url.HOST)
68+
override val featureName: String = "serpSettings"
69+
override val methods: List<String> = listOf(NATIVE_DUCK_AI_SETTING_CHANGE_METHOD_NAME)
70+
}
71+
72+
companion object {
73+
const val NATIVE_DUCK_AI_SETTING_CHANGE_METHOD_NAME = "nativeDuckAiSettingChanged"
74+
}
75+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
* Copyright (c) 2025 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.duckchat.impl.messaging
18+
19+
import com.duckduckgo.common.test.CoroutineTestRule
20+
import com.duckduckgo.duckchat.impl.DuckChatInternal
21+
import com.duckduckgo.settings.api.SettingsPageFeature
22+
import org.junit.Assert.*
23+
import org.junit.Rule
24+
import org.junit.Test
25+
import org.mockito.kotlin.mock
26+
27+
class NativeDuckAiSettingChangedHandlerTest {
28+
29+
@get:Rule
30+
val coroutineTestRule: CoroutineTestRule = CoroutineTestRule()
31+
32+
private val handler = NativeDuckAiSettingChangedHandler(
33+
duckChatInternal = mock<DuckChatInternal>(),
34+
dispatcherProvider = coroutineTestRule.testDispatcherProvider,
35+
appCoroutineScope = coroutineTestRule.testScope,
36+
settingsPageFeature = mock<SettingsPageFeature>(),
37+
).getJsMessageHandler()
38+
39+
@Test
40+
fun `only allow duckduckgo dot com domains`() {
41+
val domains = handler.allowedDomains
42+
assertEquals(1, domains.size)
43+
assertEquals("duckduckgo.com", domains.first())
44+
}
45+
46+
@Test
47+
fun `feature name is serpSettings`() {
48+
assertEquals("serpSettings", handler.featureName)
49+
}
50+
51+
@Test
52+
fun `only contains nativeDuckAiSettingChanged method`() {
53+
val methods = handler.methods
54+
assertEquals(1, methods.size)
55+
assertEquals("nativeDuckAiSettingChanged", methods[0])
56+
}
57+
}

0 commit comments

Comments
 (0)