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

Integrate privacy dashboard #5593

Merged
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 @@ -18,9 +18,9 @@ package com.duckduckgo.app.browser.omnibar.animations

import com.airbnb.lottie.LottieAnimationView
import com.duckduckgo.app.browser.R
import com.duckduckgo.app.global.model.PrivacyShield.MALICIOUS
import com.duckduckgo.app.global.model.PrivacyShield.PROTECTED
import com.duckduckgo.app.global.model.PrivacyShield.UNPROTECTED
import com.duckduckgo.app.global.model.PrivacyShield.WARNING
import com.duckduckgo.common.ui.store.AppTheme
import org.junit.Test
import org.mockito.kotlin.mock
Expand Down Expand Up @@ -80,28 +80,28 @@ class LottiePrivacyShieldAnimationHelperTest {
}

@Test
fun whenLightModeAndPrivacyShieldWarningThenUseLightAnimation() {
fun whenLightModeAndPrivacyShieldMaliciousThenUseLightAnimation() {
val holder: LottieAnimationView = mock()
val appTheme: AppTheme = mock()
whenever(appTheme.isLightModeEnabled()).thenReturn(true)
val testee = LottiePrivacyShieldAnimationHelper(appTheme)

testee.setAnimationView(holder, WARNING)
testee.setAnimationView(holder, MALICIOUS)

verify(holder).setAnimation(R.raw.unprotected_shield)
verify(holder).progress = 1.0f
verify(holder).setAnimation(R.raw.alert_red)
verify(holder).progress = 0.0f
}

@Test
fun whenDarkModeAndPrivacyShieldWarningThenUseDarkAnimation() {
fun whenDarkModeAndPrivacyShieldMaliciousThenUseDarkAnimation() {
val holder: LottieAnimationView = mock()
val appTheme: AppTheme = mock()
whenever(appTheme.isLightModeEnabled()).thenReturn(false)
val testee = LottiePrivacyShieldAnimationHelper(appTheme)

testee.setAnimationView(holder, WARNING)
testee.setAnimationView(holder, MALICIOUS)

verify(holder).setAnimation(R.raw.dark_unprotected_shield)
verify(holder).progress = 1.0f
verify(holder).setAnimation(R.raw.alert_red_dark)
verify(holder).progress = 0.0f
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ package com.duckduckgo.app.browser.omnibar.animations
import com.airbnb.lottie.LottieAnimationView
import com.duckduckgo.app.browser.R
import com.duckduckgo.app.global.model.PrivacyShield
import com.duckduckgo.app.global.model.PrivacyShield.MALICIOUS
import com.duckduckgo.app.global.model.PrivacyShield.PROTECTED
import com.duckduckgo.app.global.model.PrivacyShield.UNKNOWN
import com.duckduckgo.app.global.model.PrivacyShield.UNPROTECTED
import com.duckduckgo.app.global.model.PrivacyShield.WARNING
import com.duckduckgo.common.ui.store.AppTheme
import com.duckduckgo.di.scopes.AppScope
import com.squareup.anvil.annotations.ContributesBinding
Expand Down Expand Up @@ -54,10 +54,10 @@ class LottiePrivacyShieldAnimationHelper @Inject constructor(val appTheme: AppTh
UNKNOWN -> {
Timber.i("Shield: UNKNOWN")
}
WARNING -> {
val res = if (appTheme.isLightModeEnabled()) R.raw.unprotected_shield else R.raw.dark_unprotected_shield
MALICIOUS -> {
val res = if (appTheme.isLightModeEnabled()) R.raw.alert_red else R.raw.alert_red_dark
holder.setAnimation(res)
holder.progress = 1.0f
holder.progress = 0.0f
Timber.i("Shield: WARNING")
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import androidx.annotation.WorkerThread
import androidx.core.net.toUri
import com.duckduckgo.app.browser.UriString
import com.duckduckgo.app.browser.certificates.BypassedSSLCertificatesRepository
import com.duckduckgo.app.global.model.PrivacyShield.MALICIOUS
import com.duckduckgo.app.global.model.PrivacyShield.PROTECTED
import com.duckduckgo.app.global.model.PrivacyShield.UNKNOWN
import com.duckduckgo.app.global.model.PrivacyShield.UNPROTECTED
Expand Down Expand Up @@ -167,6 +168,7 @@ class SiteMonitor(
userAllowList = domain?.let { isAllowListed(it) } ?: false
if (duckPlayer.isDuckPlayerUri(url)) return UNKNOWN
if (userAllowList || !isHttps) return UNPROTECTED
if (maliciousSiteStatus != null) return MALICIOUS

if (!fullSiteDetailsAvailable) {
Timber.i("Shield: not fullSiteDetailsAvailable for $domain")
Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/raw/alert_red.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"v":"5.7.12","fr":24,"ip":0,"op":24,"w":130,"h":40,"nm":"error @40px_light","ddd":0,"assets":[{"id":"comp_0","nm":"Alert_Red","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Exclamation Mark","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[12,12,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-1.016,0],[0.108,-1.01],[0,0],[0.46,0],[0.049,0.457]],"o":[[-0.108,-1.01],[1.016,0],[0,0],[-0.049,0.457],[-0.46,0],[0,0]],"v":[[-1.699,-5.459],[0,-7.35],[1.699,-5.459],[0.895,2.046],[0,2.85],[-0.895,2.046]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":5,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[0,-0.828],[0.828,0],[0,0.828],[-0.828,0]],"o":[[0,0.828],[-0.828,0],[0,-0.828],[0.828,0]],"v":[[1.5,5.85],[0,7.35],[-1.5,5.85],[0,4.35]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":5,"nm":"Merge Paths 2","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape","np":5,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":96,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Circle","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[12,12,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-6.075,0],[0,6.075],[6.075,0],[0,-6.075]],"o":[[6.075,0],[0,-6.075],[-6.075,0],[0,6.075]],"v":[[0,11],[11,0],[0,-11],[-11,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333337307,0.06274510175,0.145098045468,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":96,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"Alert_Red","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[22,20,0],"ix":2,"l":2},"a":{"a":0,"k":[12,12,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"w":24,"h":24,"ip":0,"op":96,"st":0,"bm":0}],"markers":[{"tm":0,"cm":"","dr":0},{"tm":80,"cm":"","dr":0}]}
1 change: 1 addition & 0 deletions app/src/main/res/raw/alert_red_dark.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"v":"5.7.12","fr":24,"ip":0,"op":24,"w":130,"h":40,"nm":"error @40px_dark","ddd":0,"assets":[{"id":"comp_0","nm":"Alert_Red_Dark","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Exclamation Mark","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[12,12,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-1.016,0],[0.108,-1.01],[0,0],[0.46,0],[0.049,0.457]],"o":[[-0.108,-1.01],[1.016,0],[0,0],[-0.049,0.457],[-0.46,0],[0,0]],"v":[[-1.699,-5.459],[0,-7.35],[1.699,-5.459],[0.895,2.046],[0,2.85],[-0.895,2.046]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":5,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[0,-0.828],[0.828,0],[0,0.828],[-0.828,0]],"o":[[0,0.828],[-0.828,0],[0,-0.828],[0.828,0]],"v":[[1.5,5.85],[0,7.35],[-1.5,5.85],[0,4.35]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":5,"nm":"Merge Paths 2","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape","np":5,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":96,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Circle","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[12,12,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-6.075,0],[0,6.075],[6.075,0],[0,-6.075]],"o":[[6.075,0],[0,-6.075],[-6.075,0],[0,6.075]],"v":[[0,11],[11,0],[0,-11],[-11,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.329411764706,0.352941176471,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":96,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"Alert_Red_Dark","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[22,20,0],"ix":2,"l":2},"a":{"a":0,"k":[12,12,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"w":24,"h":24,"ip":0,"op":96,"st":0,"bm":0}],"markers":[{"tm":32,"cm":"","dr":0},{"tm":45,"cm":"","dr":0}]}
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,7 @@ class OmnibarLayoutViewModelTest {

@Test
fun whenPrivacyShieldChangedToWarningThenViewStateCorrect() = runTest {
val privacyShield = PrivacyShield.WARNING
val privacyShield = PrivacyShield.MALICIOUS
testee.onPrivacyShieldChanged(privacyShield)

testee.viewState.test {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@ package com.duckduckgo.app.global.model
enum class PrivacyShield {
PROTECTED,
UNPROTECTED,
WARNING,
MALICIOUS,
UNKNOWN,
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"@duckduckgo/autoconsent": "^12.8.0",
"@duckduckgo/autofill": "github:duckduckgo/duckduckgo-autofill#16.2.0",
"@duckduckgo/content-scope-scripts": "github:duckduckgo/content-scope-scripts#7.16.0",
"@duckduckgo/privacy-dashboard": "github:duckduckgo/privacy-dashboard#8.1.0",
"@duckduckgo/privacy-dashboard": "github:duckduckgo/privacy-dashboard#8.4.0",
"@duckduckgo/privacy-reference-tests": "github:duckduckgo/privacy-reference-tests#1738159777"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ class PrivacyDashboardHybridViewModel @Inject constructor(
val protectionStatus: ProtectionStatusViewState,
val cookiePromptManagementStatus: CookiePromptManagementState,
val remoteFeatureSettings: RemoteFeatureSettingsViewState,
val maliciousSiteStatus: String? = null,
)

data class ProtectionStatusViewState(
Expand Down Expand Up @@ -289,6 +290,7 @@ class PrivacyDashboardHybridViewModel @Inject constructor(
protectionStatus = protectionStatusViewStateMapper.mapFromSite(site),
cookiePromptManagementStatus = autoconsentStatusViewStateMapper.mapFromSite(site),
remoteFeatureSettings = createRemoteFeatureSettings(),
maliciousSiteStatus = site.maliciousSiteStatus?.name?.lowercase(),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fine, but I expect they ignoreCase in the JS side... :D

),
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@ class PrivacyDashboardRenderer(
val cookiePromptManagementStatusJson = cookiePromptManagementStatusAdapter.toJson(viewState.cookiePromptManagementStatus)
webView.evaluateJavascript("javascript:onChangeConsentManaged($cookiePromptManagementStatusJson);", null)

val maliciousStateJson = """{"kind": "${viewState.maliciousSiteStatus}"}"""
webView.evaluateJavascript("javascript:onChangeMaliciousSiteStatus($maliciousStateJson);", null)

// remote feature settings
val remoteFeatureSettingsAdapter = moshi.adapter(RemoteFeatureSettingsViewState::class.java)
val remoteFeatureSettingsJson = remoteFeatureSettingsAdapter.toJson(viewState.remoteFeatureSettings)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ class PrivacyDashboardRendererTest {

testee.render(aViewState())

verify(spyWebView, times(8)).evaluateJavascript(captor.capture(), eq(null))
verify(spyWebView, times(9)).evaluateJavascript(captor.capture(), eq(null))

assertNotNull(captor.allValues.find { it.startsWith("javascript:onChangeLocale") })
assertNotNull(captor.allValues.find { it.startsWith("javascript:onChangeFeatureSettings") })
Expand All @@ -123,6 +123,7 @@ class PrivacyDashboardRendererTest {
assertNotNull(captor.allValues.find { it.startsWith("javascript:onChangeUpgradedHttps") })
assertNotNull(captor.allValues.find { it.startsWith("javascript:onChangeRequestData") })
assertNotNull(captor.allValues.find { it.startsWith("javascript:onChangeConsentManaged") })
assertNotNull(captor.allValues.find { it.startsWith("javascript:onChangeMaliciousSiteStatus") })
}

fun aViewState() = ViewState(
Expand Down
Loading