Skip to content

Commit

Permalink
Merge branch 'release/5.194.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
aitorvs committed Mar 18, 2024
2 parents 5f01e2d + 1f1ea68 commit d6053ae
Show file tree
Hide file tree
Showing 355 changed files with 9,509 additions and 4,975 deletions.
1 change: 1 addition & 0 deletions ad-click/ad-click-impl/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ android {
dependencies {
anvil project(path: ':anvil-compiler')
implementation project(path: ':anvil-annotations')
implementation project(path: ':browser-api')
implementation project(path: ':ad-click-api')
implementation project(path: ':di')
implementation project(path: ':common-utils')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ package com.duckduckgo.adclick.impl
import com.duckduckgo.adclick.api.AdClickManager
import com.duckduckgo.adclick.impl.pixels.AdClickPixelName
import com.duckduckgo.adclick.impl.pixels.AdClickPixels
import com.duckduckgo.common.utils.UriString
import com.duckduckgo.app.browser.UriString
import com.duckduckgo.di.scopes.AppScope
import com.squareup.anvil.annotations.ContributesBinding
import dagger.SingleInstanceIn
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import android.net.Uri
import com.duckduckgo.adclick.api.AdClickFeatureName
import com.duckduckgo.adclick.store.AdClickAttributionLinkFormatEntity
import com.duckduckgo.adclick.store.AdClickAttributionRepository
import com.duckduckgo.common.utils.UriString
import com.duckduckgo.app.browser.UriString
import com.duckduckgo.di.scopes.AppScope
import com.duckduckgo.feature.toggles.api.FeatureToggle
import com.squareup.anvil.annotations.ContributesBinding
Expand Down
1 change: 1 addition & 0 deletions anrs/anrs-impl/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ dependencies {
implementation project(':di')
implementation project(':browser-api')
implementation project(':statistics')
implementation project(':verified-installation-api')

implementation AndroidX.core.ktx
implementation KotlinX.coroutines.core
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,14 @@ package com.duckduckgo.app.anr

import android.util.Base64
import com.duckduckgo.app.anr.CrashPixel.APPLICATION_CRASH_GLOBAL
import com.duckduckgo.app.anr.CrashPixel.APPLICATION_CRASH_GLOBAL_VERIFIED_INSTALL
import com.duckduckgo.app.anrs.store.UncaughtExceptionDao
import com.duckduckgo.app.statistics.api.OfflinePixel
import com.duckduckgo.app.statistics.api.PixelSender
import com.duckduckgo.app.statistics.pixels.Pixel.PixelType.COUNT
import com.duckduckgo.browser.api.WebViewVersionProvider
import com.duckduckgo.di.scopes.AppScope
import com.duckduckgo.verifiedinstallation.IsVerifiedPlayStoreInstall
import com.squareup.anvil.annotations.ContributesMultibinding
import io.reactivex.Completable
import javax.inject.Inject
Expand All @@ -34,6 +36,7 @@ class CrashOfflinePixelSender @Inject constructor(
private val uncaughtExceptionDao: UncaughtExceptionDao,
private val pixelSender: PixelSender,
private val webViewVersionProvider: WebViewVersionProvider,
private val isVerifiedPlayStoreInstall: IsVerifiedPlayStoreInstall,
) : OfflinePixel {
override fun send(): Completable {
return Completable.defer {
Expand All @@ -54,6 +57,16 @@ class CrashOfflinePixelSender @Inject constructor(
EXCEPTION_WEBVIEW_VERSION to webViewVersionProvider.getFullVersion(),
)

if (isVerifiedPlayStoreInstall()) {
val verifiedPixel = pixelSender.sendPixel(
pixelName = APPLICATION_CRASH_GLOBAL_VERIFIED_INSTALL.pixelName,
parameters = params,
encodedParameters = emptyMap(),
type = COUNT,
)
pixels.add(verifiedPixel.ignoreElement())
}

val pixel =
pixelSender.sendPixel(APPLICATION_CRASH_GLOBAL.pixelName, params, emptyMap(), COUNT).ignoreElement().doOnComplete {
logcat { "Sent pixel with params: $params containing exception; deleting exception with id=${exception.hash}" }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,5 @@ import com.duckduckgo.app.statistics.pixels.Pixel.PixelName

internal enum class CrashPixel(override val pixelName: String) : PixelName {
APPLICATION_CRASH_GLOBAL("m_d_ac_g"),
APPLICATION_CRASH_GLOBAL_VERIFIED_INSTALL("m_app_crashed_on_verified_play_store_install"),
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2023 DuckDuckGo
* Copyright (c) 2024 DuckDuckGo
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -14,20 +14,23 @@
* limitations under the License.
*/

package com.duckduckgo.networkprotection.impl.configuration
package com.duckduckgo.app.anr

import com.duckduckgo.app.global.api.ApiInterceptorPlugin
import com.duckduckgo.app.anr.CrashPixel.APPLICATION_CRASH_GLOBAL_VERIFIED_INSTALL
import com.duckduckgo.common.utils.plugins.pixel.PixelParamRemovalPlugin
import com.duckduckgo.common.utils.plugins.pixel.PixelParamRemovalPlugin.PixelParameter
import com.duckduckgo.di.scopes.AppScope
import com.squareup.anvil.annotations.ContributesMultibinding
import javax.inject.Inject
import okhttp3.Interceptor

@ContributesMultibinding(
scope = AppScope::class,
boundType = ApiInterceptorPlugin::class,
boundType = PixelParamRemovalPlugin::class,
)
class NetpRequestInterceptorPlugin @Inject constructor(
private val netpRequestInterceptor: NetpRequestInterceptor,
) : ApiInterceptorPlugin {
override fun getInterceptor(): Interceptor = netpRequestInterceptor
class VerifiedCrashPixelDataCleaner @Inject constructor() : PixelParamRemovalPlugin {
override fun names(): List<Pair<String, Set<PixelParameter>>> {
return listOf(
APPLICATION_CRASH_GLOBAL_VERIFIED_INSTALL.pixelName to PixelParameter.removeAtb(),
)
}
}
3 changes: 3 additions & 0 deletions anvil/anvil-annotations/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,8 @@ kotlin {

dependencies {
implementation Google.dagger
api Square.retrofit2.converter.moshi
api "com.squareup.moshi:moshi-kotlin:_"
api project(':privacy-config-api') // needed for ContributesRemoteFeature
}

Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ import kotlin.reflect.KClass
@Retention(AnnotationRetention.RUNTIME)
@Repeatable
annotation class ContributeToActivityStarter(
/** The type of the input paramters received by the Activity */
/** The type of the input parameters received by the Activity */
val paramsType: KClass<*>,
/** Declares the deeplink name for the Activity */
val screenName: String = "",
)
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,20 @@ class ContributeToActivityStarterCodeGenerator : CodeGenerator {
val content = FileSpec.buildFile(generatedPackage, moduleClassName) {
for (annotation in mapperAnnotations) {
val paramsType = annotation.paramsTypeOrNull()!!
addType(createMapperClass(paramsType, vmClass, module)).build()
val screenName = annotation.screenNameOrNull().orEmpty()
addType(createMapperClass(paramsType, screenName, vmClass, module)).build()
}
}

return createGeneratedFile(codeGenDir, generatedPackage, moduleClassName, content)
}

private fun createMapperClass(paramsType: ClassReference, vmClass: ClassReference.Psi, module: ModuleDescriptor): TypeSpec {
private fun createMapperClass(
paramsType: ClassReference,
screenName: String,
vmClass: ClassReference.Psi,
module: ModuleDescriptor,
): TypeSpec {
val moduleClassName = "${vmClass.shortName}_${paramsType.shortName}_Mapper"

return TypeSpec.classBuilder(moduleClassName)
Expand All @@ -86,6 +92,11 @@ class ContributeToActivityStarterCodeGenerator : CodeGenerator {
)
.addSuperinterface(paramToActivityMapperFqName.asClassName(module))
.addPrimaryConstructor()
.addProperty(
PropertySpec.builder("moshi", moshi.asClassName(module), KModifier.PRIVATE)
.initializer("Moshi.Builder().add(%T()).build()", kotlinJsonObjectAdapter.asClassName(module))
.build(),
)
.addFunction(
FunSpec.builder("map")
.addModifiers(KModifier.OVERRIDE)
Expand All @@ -111,6 +122,15 @@ class ContributeToActivityStarterCodeGenerator : CodeGenerator {
)
.build(),
)
.apply {
if (screenName.isBlank()) {
addFunction(emptyDeepLinkMapper(module))
} else {
addFunction(createDeeplinkMapper(module, paramsType, screenName))
addFunction(createTryCreateObjectInstance(module))
addFunction(createTryCreateActivityParamsInstance(module))
}
}
.build()
}

Expand All @@ -126,11 +146,120 @@ class ContributeToActivityStarterCodeGenerator : CodeGenerator {
return argumentAt("paramsType", 0)?.value()
}

private fun AnnotationReference.screenNameOrNull(): String? {
return argumentAt("screenName", 1)?.value() as? String?
}

private fun emptyDeepLinkMapper(module: ModuleDescriptor): FunSpec {
return FunSpec.builder("map")
.addModifiers(KModifier.OVERRIDE)
.addParameter(
"deeplinkActivityParams",
deeplinkActivityParamsFqName.asClassName(module),
)
.returns(
activityParamsFqName.asClassName(module).copy(nullable = true),
)
.addCode(
"""
return null
""".trimIndent(),
)
.build()
}

private fun createDeeplinkMapper(module: ModuleDescriptor, paramsType: ClassReference, screenName: String): FunSpec {
return FunSpec.builder("map")
.addModifiers(KModifier.OVERRIDE)
.addParameter(
"deeplinkActivityParams",
deeplinkActivityParamsFqName.asClassName(module),
)
.returns(
activityParamsFqName.asClassName(module).copy(nullable = true),
)
.addCode(
"""
val screenName = deeplinkActivityParams.screenName
if (screenName.isNullOrEmpty()) {
return null
}
val definedScreenName = %S
if (definedScreenName.isNullOrEmpty()) {
return null
}
return if (screenName == definedScreenName) {
if (deeplinkActivityParams.jsonArguments.isEmpty()) {
val instance = tryCreateObjectInstance(%T::class.java)
if (instance != null) {
return instance
}
}
tryCreateActivityParams(%T::class.java, deeplinkActivityParams)
} else {
null
}
""".trimIndent(),
screenName,
paramsType.asClassName(),
paramsType.asClassName(),
)
.build()
}

private fun createTryCreateObjectInstance(module: ModuleDescriptor): FunSpec {
return FunSpec.builder("tryCreateObjectInstance")
.addModifiers(KModifier.PRIVATE)
.addParameter("clazz", Class::class.asClassName().parameterizedBy(WildcardTypeName.producerOf(activityParamsFqName.asClassName(module))))
.addCode(
CodeBlock.builder()
.add(
"""
return kotlin.runCatching {
%T.getRawType(clazz).kotlin.objectInstance as %T
}.getOrNull()
""".trimIndent(),
moshiTypes.asClassName(module),
activityParamsFqName.asClassName(module),
).build(),
)
.returns(activityParamsFqName.asClassName(module).copy(nullable = true))
.build()
}

private fun createTryCreateActivityParamsInstance(module: ModuleDescriptor): FunSpec {
return FunSpec.builder("tryCreateActivityParams")
.addModifiers(KModifier.PRIVATE)
.addParameter("clazz", Class::class.asClassName().parameterizedBy(WildcardTypeName.producerOf(activityParamsFqName.asClassName(module))))
.addParameter(
"deeplinkActivityParams",
deeplinkActivityParamsFqName.asClassName(module),
)
.addCode(
CodeBlock.builder()
.add(
"""
return kotlin.runCatching {
moshi.adapter(clazz).fromJson(deeplinkActivityParams.jsonArguments)
}.getOrNull()
""".trimIndent(),
).build(),
)
.returns(activityParamsFqName.asClassName(module).copy(nullable = true))
.build()
}

companion object {
private val appScopeFqName = FqName("com.duckduckgo.di.scopes.AppScope")
private val paramToActivityMapperFqName = FqName("com.duckduckgo.navigation.api.GlobalActivityStarter.ParamToActivityMapper")
private val activityParamsFqName = FqName("com.duckduckgo.navigation.api.GlobalActivityStarter.ActivityParams")
private val deeplinkActivityParamsFqName = FqName("com.duckduckgo.navigation.api.GlobalActivityStarter.DeeplinkActivityParams")
private val appCompatActivityFqName = FqName("androidx.appcompat.app.AppCompatActivity")
private val duckduckgoActivityFqName = FqName("com.duckduckgo.common.ui.DuckDuckGoActivity")
private val moshi = FqName("com.squareup.moshi.Moshi")
private val kotlinJsonObjectAdapter = FqName("com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory")
private val moshiTypes = FqName("com.squareup.moshi.Types")
}
}
Loading

0 comments on commit d6053ae

Please sign in to comment.