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

Animalsniffer check #771

Merged
merged 9 commits into from
Jan 28, 2025
70 changes: 70 additions & 0 deletions animal-sniffer-signature/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import ru.vyarus.gradle.plugin.animalsniffer.info.SignatureInfoTask
import ru.vyarus.gradle.plugin.animalsniffer.signature.BuildSignatureTask

plugins {
id("com.android.library")
id("ru.vyarus.animalsniffer")
}

android {
namespace = "otel.animalsniffer.signature"
compileSdk = (property("android.compileSdk") as String).toInt()
}

description = "Build tool to generate the Animal Sniffer Android signature"

val signatureJar =
configurations.create("signatureJar") {
isCanBeConsumed = false
isCanBeResolved = false
}
val signatureJarClasspath =
configurations.create("signatureJarClasspath") {
isCanBeConsumed = false
isCanBeResolved = true
extendsFrom(signatureJar)
}
val generatedSignature =
configurations.create("generatedSignature") {
isCanBeConsumed = true
isCanBeResolved = false
}
configurations.add(signatureJar)
configurations.add(signatureJarClasspath)
configurations.add(generatedSignature)

dependencies {
signature("com.toasttab.android:gummy-bears-api-${project.property("android.minSdk")}:0.9.0@signature")
breedx-splk marked this conversation as resolved.
Show resolved Hide resolved
signatureJar(libs.desugarJdkLibs)
}

val signatureSimpleName = "android.signature"
val signatureBuilderTask =
tasks.register("buildSignature", BuildSignatureTask::class.java) {
files(signatureJarClasspath) // All the jar files here will be added to the signature file.
signatures(configurations.signature) // We'll extend from the existing signatures added to this config.
outputName = signatureSimpleName // Name for the generated signature file.
}

// Exposing the "generatedSignature" consumable config to be used in other subprojects
artifacts {
add(
"generatedSignature",
project.provider {
File(
signatureBuilderTask
.get()
.outputs.files.singleFile,
signatureSimpleName,
)
},
) {
builtBy(signatureBuilderTask)
}
}

// Utility task to show what's in the signature file
tasks.register("printSignature", SignatureInfoTask::class.java) {
signature = signatureBuilderTask.get().outputFiles
depth = 1
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ plugins {
id("org.jetbrains.kotlin.android")
id("otel.errorprone-conventions")
id("kotlin-kapt")
id("otel.animalsniffer-conventions")
}

val javaVersion = rootProject.extra["java_version"] as JavaVersion
Expand Down Expand Up @@ -44,6 +45,7 @@ tasks.withType<Test> {

val libs = extensions.getByType<VersionCatalogsExtension>().named("libs")
dependencies {
implementation(libs.findLibrary("androidx-annotation").get())
implementation(libs.findLibrary("findbugs-jsr305").get())
implementation(libs.findLibrary("auto-service-annotations").get())
kapt(libs.findLibrary("auto-service-processor").get())
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import java.util.Locale
import ru.vyarus.gradle.plugin.animalsniffer.AnimalSniffer

plugins {
id("com.android.library")
id("ru.vyarus.animalsniffer")
}

dependencies {
signature(project(path = ":animal-sniffer-signature", configuration = "generatedSignature"))
}

val capitalizedVariantNames = mutableListOf<String>()
androidComponents.onVariants { variant ->
val capitalizedName =
variant.name.replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() }
capitalizedVariantNames.add(capitalizedName)
}

afterEvaluate {
capitalizedVariantNames.forEach { capitalizedName ->
tasks.named("pre${capitalizedName}Build").configure {
finalizedBy("animalsniffer$capitalizedName")
}
}
}

// Any class, method or field annotated with this annotation will be ignored by animal sniffer.
animalsniffer.annotation = "androidx.annotation.RequiresApi"

tasks.withType<AnimalSniffer> {
// always having declared output makes this task properly participate in tasks up-to-date checks
reports.text.required.set(true)
}

This file was deleted.

3 changes: 2 additions & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ opentelemetry-platform-alpha = { module = "io.opentelemetry.instrumentation:open
opentelemetry-platform = { module = "io.opentelemetry.instrumentation:opentelemetry-instrumentation-bom" }
androidx-navigation-fragment = "androidx.navigation:navigation-fragment:2.7.7"
androidx-core = "androidx.core:core:1.15.0"
androidx-annotation = "androidx.annotation:annotation:1.9.1"
androidx-lifecycle-process = "androidx.lifecycle:lifecycle-process:2.8.7"
findbugs-jsr305 = "com.google.code.findbugs:jsr305:3.0.2"
byteBuddy = { module = "net.bytebuddy:byte-buddy", version.ref = "byteBuddy" }
Expand Down Expand Up @@ -66,7 +67,7 @@ errorprone-javac = "com.google.errorprone:javac:9+181-r4173-1"
spotless-plugin = { module = "com.diffplug.spotless:spotless-plugin-gradle", version.ref = "spotless" }
errorprone-plugin = "net.ltgt.gradle:gradle-errorprone-plugin:4.1.0"
nullaway-plugin = "net.ltgt.gradle:gradle-nullaway-plugin:2.2.0"
animalsniffer-plugin = "ru.vyarus:gradle-animalsniffer-plugin:1.7.2"
animalsniffer-plugin = "ru.vyarus:gradle-animalsniffer-plugin:2.0.0"
android-plugin = { module = "com.android.tools.build:gradle", version.ref = "androidPlugin" }
byteBuddy-plugin = { module = "net.bytebuddy:byte-buddy-gradle-plugin", version.ref = "byteBuddy" }
kotlin-plugin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin" }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@

package io.opentelemetry.instrumentation.library.httpurlconnection;

import android.annotation.SuppressLint;
import android.os.Build;
import android.os.SystemClock;
import androidx.annotation.RequiresApi;
import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.library.httpurlconnection.internal.HttpUrlConnectionSingletons;
import io.opentelemetry.instrumentation.library.httpurlconnection.internal.RequestPropertySetter;
Expand Down Expand Up @@ -77,7 +78,15 @@ public static int replacementForContentLength(URLConnection connection) {
}

public static long replacementForContentLengthLong(URLConnection connection) {
return replace(connection, () -> connection.getContentLengthLong());
return replace(
Copy link
Contributor

Choose a reason for hiding this comment

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

Oh, did this catch one already then!?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, the method getContentLengthLong() is available starting from API 24 so animalsniffer complains about it because our min is 21. However, for this particular case, this method is guaranteed to be called on apps with at least min API 24 so there's no need to address it, so to disable animalsniffer for this case only we have to annotate the class/method/field with @RequiresApi where this call is made, and I tried first to annotate the parent method replacementForContentLengthLong, though that didn't work, because the call to getContentLengthLong() was made in a lambda and it seems like animalsniffer doesn't check those scenarios, so for it to work I had to turn the lambda into an anonymous class and then annotate the actual method inside where the call to getContentLengthLong() is made.

connection,
new ResultProvider<Long>() {
@RequiresApi(Build.VERSION_CODES.N)
@Override
public Long get() {
return connection.getContentLengthLong();
}
});
}

public static long replacementForExpiration(URLConnection connection) {
Expand Down Expand Up @@ -105,10 +114,17 @@ public static int replacementForHeaderFieldInt(
return replace(connection, () -> connection.getHeaderFieldInt(name, Default));
}

@SuppressLint("NewApi")
public static long replacementForHeaderFieldLong(
URLConnection connection, String name, long Default) {
return replace(connection, () -> connection.getHeaderFieldLong(name, Default));
return replace(
connection,
new ResultProvider<Long>() {
@RequiresApi(Build.VERSION_CODES.N)
@Override
public Long get() {
return connection.getHeaderFieldLong(name, Default);
}
});
}

public static long replacementForHeaderFieldDate(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ public void onActivityPaused(@NonNull Activity activity) {
}
}

@RequiresApi(api = Build.VERSION_CODES.N)
static class PerActivityListener implements Window.OnFrameMetricsAvailableListener {

private final Activity activity;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import android.os.Build;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import io.opentelemetry.android.common.RumConstants;
import io.opentelemetry.android.common.internal.features.networkattributes.data.CurrentNetwork;
import io.opentelemetry.android.common.internal.features.networkattributes.data.NetworkState;
Expand Down Expand Up @@ -75,13 +76,18 @@ private void startMonitoring(Supplier<NetworkRequest> createNetworkMonitoringReq

private void registerNetworkCallbacks(Supplier<NetworkRequest> createNetworkMonitoringRequest) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
connectivityManager.registerDefaultNetworkCallback(new ConnectionMonitor());
registerNetworkCallbackApi24();
} else {
NetworkRequest networkRequest = createNetworkMonitoringRequest.get();
connectivityManager.registerNetworkCallback(networkRequest, new ConnectionMonitor());
}
}

@RequiresApi(Build.VERSION_CODES.N)
private void registerNetworkCallbackApi24() {
connectivityManager.registerDefaultNetworkCallback(new ConnectionMonitor());
}

/** Returns up-to-date {@linkplain CurrentNetwork current network information}. */
public CurrentNetwork refreshNetworkStatus() {
try {
Expand Down
1 change: 1 addition & 0 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ include(":instrumentation:httpurlconnection:agent")
include(":instrumentation:httpurlconnection:library")
include(":instrumentation:httpurlconnection:testing")
include(":test-common")
include(":animal-sniffer-signature")
include(":instrumentation:android-instrumentation")
include(":common")
include(":services")
Expand Down
Loading