Skip to content

Commit e003507

Browse files
authored
Support multiple script injection through RC flags (#7141)
Task/Issue URL: https://app.asana.com/1/137249556945/project/72649045549333/task/1211963296480305?focus=true ### Description Support multiple script injection through RC flags ### Steps to test this PR _Feature 1_ - [ ] Set `const val PRIVACY_REMOTE_CONFIG_URL = "https://api.jsonblob.com/019a978f-2dd6-79fe-8f8e-fc44b566dd19"` and clean install the app - [ ] Open a site - [ ] Open Chrome console and check logs for `[large script] n Posting initial ping...` With n in 0..19 ### UI changes n/a
1 parent 53a06fd commit e003507

File tree

5 files changed

+43
-45
lines changed

5 files changed

+43
-45
lines changed

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

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ private const val delay = "\$DELAY$"
4040
private const val postInitialPing = "\$POST_INITIAL_PING$"
4141
private const val replyToNativeMessages = "\$REPLY_TO_NATIVE_MESSAGES$"
4242
private const val objectName = "\$OBJECT_NAME$"
43+
private const val scriptID = "\$SCRIPT_ID$"
4344

4445
interface WebViewCompatTestHelper {
4546
suspend fun configureWebViewForWebViewCompatTest(webView: DuckDuckGoWebView, isBlobDownloadWebViewFeatureEnabled: Boolean)
@@ -112,9 +113,10 @@ class RealWebViewCompatTestHelper @Inject constructor(
112113
val config = getWebViewCompatConfig()
113114

114115
val useDedicatedListener = !config.useBlobDownloadsMessageListener || !isBlobDownloadWebViewFeatureEnabled
116+
val numberOfScriptsToInject = config.settings?.numberOfScriptsToInject ?: 0L
115117

116118
val script = withContext(dispatchers.io()) {
117-
if (!webViewCompatFeature.self().isEnabled()) return@withContext null
119+
if (!webViewCompatFeature.self().isEnabled() || numberOfScriptsToInject == 0L) return@withContext null
118120
val scriptResourceId = if (config.useComplexScript) {
119121
R.raw.webviewcompat_complex_test_script
120122
} else if (config.useLargeScript) {
@@ -133,17 +135,21 @@ class RealWebViewCompatTestHelper @Inject constructor(
133135
?.replace(objectName, if (useDedicatedListener) "webViewCompatTestObj" else "ddgBlobDownloadObj")
134136
} ?: return
135137

136-
withContext(dispatchers.main()) {
137-
webViewCompatWrapper.addDocumentStartJavaScript(webView, script, setOf("*"))
138-
139-
if (useDedicatedListener) {
140-
webViewCompatWrapper.addWebMessageListener(
141-
webView,
142-
"webViewCompatTestObj",
143-
setOf("*"),
144-
) { view, message, sourceOrigin, isMainFrame, replyProxy ->
145-
webView.findViewTreeLifecycleOwner()?.lifecycleScope?.launch {
146-
handleWebViewCompatMessage(message, replyProxy, isMainFrame)
138+
for (i in 0 until numberOfScriptsToInject) {
139+
withContext(dispatchers.io()) { script.replace(scriptID, i.toString()) }.let {
140+
withContext(dispatchers.main()) {
141+
webViewCompatWrapper.addDocumentStartJavaScript(webView, it, setOf("*"))
142+
143+
if (useDedicatedListener && i == 0L) {
144+
webViewCompatWrapper.addWebMessageListener(
145+
webView,
146+
"webViewCompatTestObj",
147+
setOf("*"),
148+
) { view, message, sourceOrigin, isMainFrame, replyProxy ->
149+
webView.findViewTreeLifecycleOwner()?.lifecycleScope?.launch {
150+
handleWebViewCompatMessage(message, replyProxy, isMainFrame)
151+
}
152+
}
147153
}
148154
}
149155
}

app/src/main/java/com/duckduckgo/app/browser/webview/WebViewCompatFeature.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,4 +61,5 @@ interface WebViewCompatFeature {
6161
data class WebViewCompatFeatureSettings(
6262
val jsInitialPingDelay: Long = 0,
6363
val initialPingDelay: Long = 0,
64+
val numberOfScriptsToInject: Long = 1,
6465
)

app/src/main/res/raw/webviewcompat_complex_test_script.js

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
const delay = $DELAY$;
44
const postInitialPing = $POST_INITIAL_PING$;
55
const replyToNativeMessages = $REPLY_TO_NATIVE_MESSAGES$;
6-
const messagePrefix = 'webViewCompat ';
6+
const messagePrefix = 'webViewCompat $SCRIPT_ID$';
77

88
// ============================================================================
99
// MESSAGE HANDLING (ORIGINAL WEBVIEWCOMPAT FUNCTIONALITY)
@@ -14,61 +14,51 @@
1414

1515
// Send initial ping if configured
1616
if (postInitialPing) {
17-
console.log('Posting initial ping...');
17+
console.log('$SCRIPT_ID$ Posting initial ping...');
1818
if (delay > 0) {
1919
setTimeout(() => {
2020
ddgObj.postMessage(webViewCompatPingMessage);
21-
stateManager.setState(state => ({
22-
...state,
23-
messageCount: state.messageCount + 1,
24-
lastMessageTime: Date.now()
25-
}));
2621
}, delay);
2722
} else {
2823
ddgObj.postMessage(webViewCompatPingMessage);
29-
stateManager.setState(state => ({
30-
...state,
31-
messageCount: state.messageCount + 1,
32-
lastMessageTime: Date.now()
33-
}));
3424
}
3525
}
3626

3727
// Listen to ddgObj messages
3828
ddgObj.addEventListener('message', function(event) {
39-
console.log("$OBJECT_NAME$ received", event.data);
29+
console.log("[complex script] $OBJECT_NAME$-$SCRIPT_ID$ received", event.data);
4030

4131
stateManager.setState(state => ({
4232
...state,
4333
messageCount: state.messageCount + 1,
4434
lastMessageTime: Date.now()
4535
}));
4636

47-
eventBus.emit('message-received', { source: '$OBJECT_NAME$', data: event.data });
37+
eventBus.emit('message-received', { source: '$OBJECT_NAME$-$SCRIPT_ID$', data: event.data });
4838

4939
if (replyToNativeMessages && supportedMessages.includes(event.data)) {
50-
const response = messagePrefix + event.data + " from $OBJECT_NAME$";
40+
const response = messagePrefix + event.data + " from $OBJECT_NAME$-$SCRIPT_ID$";
5141
ddgObj.postMessage(response);
52-
throttledLog('Sent response:', response);
42+
throttledLog('[complex-script]-$SCRIPT_ID$ Sent response:', response);
5343
}
5444
});
5545

5646
// Listen to window messages
5747
window.addEventListener('message', function(event) {
58-
console.log("window received", event.data);
48+
console.log("[complex-script] window-$SCRIPT_ID$ received", event.data);
5949

6050
stateManager.setState(state => ({
6151
...state,
6252
messageCount: state.messageCount + 1,
6353
lastMessageTime: Date.now()
6454
}));
6555

66-
eventBus.emit('message-received', { source: 'window', data: event.data });
56+
eventBus.emit('message-received', { source: 'window-$SCRIPT_ID$', data: event.data });
6757

6858
if (replyToNativeMessages && supportedMessages.includes(event.data)) {
69-
const response = messagePrefix + event.data + " from window";
59+
const response = messagePrefix + event.data + " from window-$SCRIPT_ID$";
7060
ddgObj.postMessage(response);
71-
throttledLog('Sent response:', response);
61+
throttledLog('[complex-script]-$SCRIPT_ID$ Sent response:', response);
7262
}
7363
});
7464

app/src/main/res/raw/webviewcompat_large_test_script.js

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1944,7 +1944,7 @@
19441944
const delay = $DELAY$;
19451945
const postInitialPing = $POST_INITIAL_PING$;
19461946
const replyToNativeMessages = $REPLY_TO_NATIVE_MESSAGES$;
1947-
const messagePrefix = 'webViewCompat ';
1947+
const messagePrefix = 'webViewCompat-$SCRIPT_ID$ ';
19481948

19491949
// Initialize state manager and event bus for message tracking
19501950

@@ -1953,7 +1953,7 @@
19531953

19541954
// Send initial ping if configured
19551955
if (postInitialPing) {
1956-
console.log('[large script] Posting initial ping...');
1956+
console.log('[large script]-$SCRIPT_ID$ Posting initial ping...');
19571957
if (delay > 0) {
19581958
setTimeout(() => {
19591959
ddgObj.postMessage(webViewCompatPingMessage);
@@ -1965,27 +1965,27 @@
19651965

19661966
// Listen to ddgObj messages
19671967
ddgObj.addEventListener('message', function(event) {
1968-
console.log("$OBJECT_NAME$ received", event.data);
1968+
console.log("[large script]-$OBJECT_NAME$-$SCRIPT_ID$ received", event.data);
19691969

19701970

19711971

1972-
eventBus.emit('message-received', { source: '$OBJECT_NAME$', data: event.data });
1972+
eventBus.emit('message-received', { source: '$OBJECT_NAME$-$SCRIPT_ID$', data: event.data });
19731973

19741974
if (replyToNativeMessages && supportedMessages.includes(event.data)) {
1975-
const response = messagePrefix + event.data + " from $OBJECT_NAME$";
1975+
const response = messagePrefix + event.data + " from $OBJECT_NAME$-$SCRIPT_ID$";
19761976
ddgObj.postMessage(response);
1977-
console.log('Sent response:', response);
1977+
console.log('[large script]-$SCRIPT_ID$ Sent response:', response);
19781978
}
19791979
});
19801980

19811981
// Listen to window messages
19821982
window.addEventListener('message', function(event) {
1983-
console.log("window received", event.data);
1983+
console.log("[large script]-window received-$SCRIPT_ID$", event.data);
19841984

19851985
if (replyToNativeMessages && supportedMessages.includes(event.data)) {
19861986
const response = messagePrefix + event.data + " from window";
19871987
ddgObj.postMessage(response);
1988-
console.log('Sent response:', response);
1988+
console.log('[large script]-$SCRIPT_ID$ Sent response:', response);
19891989
}
19901990
});
19911991

app/src/main/res/raw/webviewcompat_test_script.js

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,13 @@
66
const delay = $DELAY$;
77
const postInitialPing = $POST_INITIAL_PING$;
88
const replyToNativeMessages = $REPLY_TO_NATIVE_MESSAGES$;
9-
const messagePrefix = 'webViewCompat '
9+
const messagePrefix = 'webViewCompat-$SCRIPT_ID$ ';
1010

1111
const webViewCompatPingMessage = messagePrefix + 'Ping:' + window.location.href + ' ' + delay + 'ms'
1212

1313

1414
if (postInitialPing) {
15+
console.log('$SCRIPT_ID$ Posting initial ping...');
1516
if (delay > 0) {
1617
setTimeout(() => {
1718
ddgObj.postMessage(webViewCompatPingMessage)
@@ -23,16 +24,16 @@
2324

2425

2526
ddgObj.addEventListener('message', function(event) {
26-
console.log("$OBJECT_NAME$ received", event.data)
27+
console.log("$OBJECT_NAME$-$SCRIPT_ID$ received", event.data)
2728
if (replyToNativeMessages && supportedMessages.includes(event.data)) {
28-
ddgObj.postMessage(messagePrefix + event.data + " from $OBJECT_NAME$")
29+
ddgObj.postMessage(messagePrefix + event.data + " from $OBJECT_NAME$-$SCRIPT_ID$")
2930
}
3031
});
3132

3233
window.addEventListener('message', function(event) {
33-
console.log("window received", event.data)
34+
console.log("window-$SCRIPT_ID$ received", event.data)
3435
if (replyToNativeMessages && supportedMessages.includes(event.data)) {
35-
ddgObj.postMessage(messagePrefix + event.data + " from window")
36+
ddgObj.postMessage(messagePrefix + event.data + " from window-$SCRIPT_ID$")
3637
}
3738
});
3839
})();

0 commit comments

Comments
 (0)