Skip to content

Commit 1cb6abb

Browse files
authored
Merge pull request #3029 from DataDog/tvaleev/feature/RUM-12635-wrapper-support
RUM-12635: RUM support for Cronet
2 parents 0c156cc + c524465 commit 1cb6abb

File tree

57 files changed

+5140
-174
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+5140
-174
lines changed

dd-sdk-android-core/api/apiSurface

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,21 @@ interface com.datadog.android.api.feature.FeatureSdkCore : com.datadog.android.a
147147
interface com.datadog.android.api.feature.StorageBackedFeature : Feature
148148
val requestFactory: com.datadog.android.api.net.RequestFactory
149149
val storageConfiguration: com.datadog.android.api.storage.FeatureStorageConfiguration
150+
interface com.datadog.android.api.instrumentation.network.ExtendedRequestInfo
151+
fun <T> tag(Class<T>): T?
152+
fun <T> HttpRequestInfo.tag(Class<T>): T?
153+
interface com.datadog.android.api.instrumentation.network.HttpRequestInfo
154+
val url: String
155+
val headers: Map<String, List<String>>
156+
val contentType: String?
157+
val method: String
158+
fun contentLength(): Long?
159+
interface com.datadog.android.api.instrumentation.network.HttpResponseInfo
160+
val url: String
161+
val statusCode: Int
162+
val headers: Map<String, List<String>>
163+
val contentType: String?
164+
val contentLength: Long?
150165
data class com.datadog.android.api.net.Request
151166
constructor(String, String, String, Map<String, String>, ByteArray, String? = null)
152167
data class com.datadog.android.api.net.RequestExecutionContext
@@ -290,6 +305,29 @@ interface com.datadog.android.core.internal.net.FirstPartyHostHeaderTypeResolver
290305
fun headerTypesForUrl(okhttp3.HttpUrl): Set<com.datadog.android.trace.TracingHeaderType>
291306
fun getAllHeaderTypes(): Set<com.datadog.android.trace.TracingHeaderType>
292307
fun isEmpty(): Boolean
308+
object com.datadog.android.core.internal.net.HttpSpec
309+
object Method
310+
const val GET: String
311+
const val POST: String
312+
const val PATCH: String
313+
const val PUT: String
314+
const val HEAD: String
315+
const val DELETE: String
316+
const val TRACE: String
317+
const val OPTIONS: String
318+
const val CONNECT: String
319+
fun values()
320+
object Headers
321+
const val CONTENT_TYPE: String
322+
const val CONTENT_LENGTH: String
323+
const val WEBSOCKET_ACCEPT_HEADER: String
324+
object ContentType
325+
const val TEXT_PLAIN: String
326+
const val TEXT_EVENT_STREAM: String
327+
const val APPLICATION_GRPC: String
328+
const val APPLICATION_GRPC_PROTO: String
329+
const val APPLICATION_GRPC_JSON: String
330+
fun isStream(String?): Boolean
293331
interface com.datadog.android.core.internal.persistence.Deserializer<P: Any, R: Any>
294332
fun deserialize(P): R?
295333
fun java.io.File.canReadSafe(com.datadog.android.api.InternalLogger): Boolean

dd-sdk-android-core/api/dd-sdk-android-core.api

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,30 @@ public abstract interface class com/datadog/android/api/feature/StorageBackedFea
443443
public abstract fun getStorageConfiguration ()Lcom/datadog/android/api/storage/FeatureStorageConfiguration;
444444
}
445445

446+
public abstract interface class com/datadog/android/api/instrumentation/network/ExtendedRequestInfo {
447+
public abstract fun tag (Ljava/lang/Class;)Ljava/lang/Object;
448+
}
449+
450+
public final class com/datadog/android/api/instrumentation/network/ExtendedRequestInfoKt {
451+
public static final fun tag (Lcom/datadog/android/api/instrumentation/network/HttpRequestInfo;Ljava/lang/Class;)Ljava/lang/Object;
452+
}
453+
454+
public abstract interface class com/datadog/android/api/instrumentation/network/HttpRequestInfo {
455+
public abstract fun contentLength ()Ljava/lang/Long;
456+
public abstract fun getContentType ()Ljava/lang/String;
457+
public abstract fun getHeaders ()Ljava/util/Map;
458+
public abstract fun getMethod ()Ljava/lang/String;
459+
public abstract fun getUrl ()Ljava/lang/String;
460+
}
461+
462+
public abstract interface class com/datadog/android/api/instrumentation/network/HttpResponseInfo {
463+
public abstract fun getContentLength ()Ljava/lang/Long;
464+
public abstract fun getContentType ()Ljava/lang/String;
465+
public abstract fun getHeaders ()Ljava/util/Map;
466+
public abstract fun getStatusCode ()I
467+
public abstract fun getUrl ()Ljava/lang/String;
468+
}
469+
446470
public final class com/datadog/android/api/net/Request {
447471
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;[BLjava/lang/String;)V
448472
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;[BLjava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
@@ -797,6 +821,41 @@ public abstract interface class com/datadog/android/core/internal/net/FirstParty
797821
public abstract fun isFirstPartyUrl (Lokhttp3/HttpUrl;)Z
798822
}
799823

824+
public final class com/datadog/android/core/internal/net/HttpSpec {
825+
public static final field INSTANCE Lcom/datadog/android/core/internal/net/HttpSpec;
826+
}
827+
828+
public final class com/datadog/android/core/internal/net/HttpSpec$ContentType {
829+
public static final field APPLICATION_GRPC Ljava/lang/String;
830+
public static final field APPLICATION_GRPC_JSON Ljava/lang/String;
831+
public static final field APPLICATION_GRPC_PROTO Ljava/lang/String;
832+
public static final field INSTANCE Lcom/datadog/android/core/internal/net/HttpSpec$ContentType;
833+
public static final field TEXT_EVENT_STREAM Ljava/lang/String;
834+
public static final field TEXT_PLAIN Ljava/lang/String;
835+
public final fun isStream (Ljava/lang/String;)Z
836+
}
837+
838+
public final class com/datadog/android/core/internal/net/HttpSpec$Headers {
839+
public static final field CONTENT_LENGTH Ljava/lang/String;
840+
public static final field CONTENT_TYPE Ljava/lang/String;
841+
public static final field INSTANCE Lcom/datadog/android/core/internal/net/HttpSpec$Headers;
842+
public static final field WEBSOCKET_ACCEPT_HEADER Ljava/lang/String;
843+
}
844+
845+
public final class com/datadog/android/core/internal/net/HttpSpec$Method {
846+
public static final field CONNECT Ljava/lang/String;
847+
public static final field DELETE Ljava/lang/String;
848+
public static final field GET Ljava/lang/String;
849+
public static final field HEAD Ljava/lang/String;
850+
public static final field INSTANCE Lcom/datadog/android/core/internal/net/HttpSpec$Method;
851+
public static final field OPTIONS Ljava/lang/String;
852+
public static final field PATCH Ljava/lang/String;
853+
public static final field POST Ljava/lang/String;
854+
public static final field PUT Ljava/lang/String;
855+
public static final field TRACE Ljava/lang/String;
856+
public final fun values ()Ljava/util/List;
857+
}
858+
800859
public abstract interface class com/datadog/android/core/internal/persistence/Deserializer {
801860
public abstract fun deserialize (Ljava/lang/Object;)Ljava/lang/Object;
802861
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/*
2+
* Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0.
3+
* This product includes software developed at Datadog (https://www.datadoghq.com/).
4+
* Copyright 2016-Present Datadog, Inc.
5+
*/
6+
package com.datadog.android.api.instrumentation.network
7+
8+
/**
9+
* This interface indicates that the request supports non HTTP-specified methods.
10+
*/
11+
interface ExtendedRequestInfo {
12+
13+
/**
14+
* Returns the tag attached with type as a key, or null if no tag is attached with that key.
15+
*/
16+
fun <T> tag(type: Class<out T>): T?
17+
}
18+
19+
/**
20+
* Returns the tag attached with type as a key, or null if no tag is attached with that key.
21+
*/
22+
fun <T> HttpRequestInfo.tag(type: Class<out T>): T? = if (this is ExtendedRequestInfo) this.tag(type) else null
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0.
3+
* This product includes software developed at Datadog (https://www.datadoghq.com/).
4+
* Copyright 2016-Present Datadog, Inc.
5+
*/
6+
package com.datadog.android.api.instrumentation.network
7+
8+
/**
9+
* Represents information about an HTTP request.
10+
*/
11+
interface HttpRequestInfo {
12+
/**
13+
* The URL associated with the HTTP request.
14+
*/
15+
val url: String
16+
17+
/**
18+
* Represents the HTTP headers associated with the request.
19+
*/
20+
val headers: Map<String, List<String>>
21+
22+
/**
23+
* The MIME type of the payload associated with the HTTP request or response, represented
24+
* as a string. Can be null if the content type is unspecified.
25+
*/
26+
val contentType: String?
27+
28+
/**
29+
* Represents the HTTP method associated with the request.
30+
*/
31+
val method: String
32+
33+
/**
34+
* Retrieves the content length of the HTTP request.
35+
*
36+
* @return the length of the content in bytes, or null if the content length is unavailable.
37+
*/
38+
fun contentLength(): Long?
39+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0.
3+
* This product includes software developed at Datadog (https://www.datadoghq.com/).
4+
* Copyright 2016-Present Datadog, Inc.
5+
*/
6+
package com.datadog.android.api.instrumentation.network
7+
8+
/**
9+
* Represents information about an HTTP response.
10+
*/
11+
interface HttpResponseInfo {
12+
/**
13+
* Represents the URL associated with an HTTP response.
14+
*/
15+
val url: String
16+
17+
/**
18+
* Represents the HTTP status code associated with the response.
19+
*/
20+
val statusCode: Int
21+
22+
/**
23+
* Represents the HTTP headers associated with a response.
24+
*/
25+
val headers: Map<String, List<String>>
26+
27+
/**
28+
* Represents the MIME type of the payload associated with an HTTP response.
29+
*/
30+
val contentType: String?
31+
32+
/**
33+
* Retrieves the content length from the response information.
34+
*
35+
* @return the content length as a Long if available, or null if it cannot be determined.
36+
*/
37+
val contentLength: Long?
38+
}
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
/*
2+
* Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0.
3+
* This product includes software developed at Datadog (https://www.datadoghq.com/).
4+
* Copyright 2016-Present Datadog, Inc.
5+
*/
6+
package com.datadog.android.core.internal.net
7+
8+
import com.datadog.android.lint.InternalApi
9+
10+
/**
11+
* HTTP specification constants and utilities.
12+
*/
13+
@InternalApi
14+
object HttpSpec {
15+
16+
/**
17+
* Standard HTTP request methods.
18+
*/
19+
object Method {
20+
/** HTTP GET method. */
21+
const val GET: String = "GET"
22+
23+
/** HTTP POST method. */
24+
const val POST: String = "POST"
25+
26+
/** HTTP PATCH method. */
27+
const val PATCH: String = "PATCH"
28+
29+
/** HTTP PUT method. */
30+
const val PUT: String = "PUT"
31+
32+
/** HTTP HEAD method. */
33+
const val HEAD: String = "HEAD"
34+
35+
/** HTTP DELETE method. */
36+
const val DELETE: String = "DELETE"
37+
38+
/** HTTP TRACE method. */
39+
const val TRACE: String = "TRACE"
40+
41+
/** HTTP OPTIONS method. */
42+
const val OPTIONS: String = "OPTIONS"
43+
44+
/** HTTP CONNECT method. */
45+
const val CONNECT: String = "CONNECT"
46+
47+
/**
48+
* Returns a list of all HTTP methods.
49+
*/
50+
fun values() = listOf(GET, POST, PATCH, PUT, HEAD, DELETE, TRACE, OPTIONS, CONNECT)
51+
}
52+
53+
/**
54+
* Standard HTTP header names.
55+
*/
56+
object Headers {
57+
/** Content-Type header name. */
58+
const val CONTENT_TYPE: String = "Content-Type"
59+
60+
/** Content-Length header name. */
61+
const val CONTENT_LENGTH: String = "Content-Length"
62+
63+
/** Sec-WebSocket-Accept header name. */
64+
const val WEBSOCKET_ACCEPT_HEADER: String = "Sec-WebSocket-Accept"
65+
}
66+
67+
/**
68+
* HTTP content type values and utilities.
69+
*/
70+
object ContentType {
71+
72+
/** Plain text content type. */
73+
const val TEXT_PLAIN: String = "text/plain"
74+
75+
/** Server-Sent Events content type. */
76+
const val TEXT_EVENT_STREAM: String = "text/event-stream"
77+
78+
/** gRPC content type. */
79+
const val APPLICATION_GRPC: String = "application/grpc"
80+
81+
/** gRPC with Protocol Buffers content type. */
82+
const val APPLICATION_GRPC_PROTO: String = "application/grpc+proto"
83+
84+
/** gRPC with JSON content type. */
85+
const val APPLICATION_GRPC_JSON: String = "application/grpc+json"
86+
87+
/**
88+
* Checks if the given content type represents a streaming protocol.
89+
* @param contentType the content type to check
90+
* @return true if the content type is a stream type, false otherwise
91+
*/
92+
fun isStream(contentType: String?): Boolean {
93+
return contentType != null && contentType in STREAM_CONTENT_TYPES
94+
}
95+
96+
private val STREAM_CONTENT_TYPES = setOf(
97+
TEXT_EVENT_STREAM,
98+
APPLICATION_GRPC,
99+
APPLICATION_GRPC_PROTO,
100+
APPLICATION_GRPC_JSON
101+
)
102+
}
103+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0.
3+
* This product includes software developed at Datadog (https://www.datadoghq.com/).
4+
* Copyright 2016-Present Datadog, Inc.
5+
*/
6+
7+
package com.datadog.android.api.instrumentation.network
8+
9+
import org.assertj.core.api.AbstractObjectAssert
10+
import org.assertj.core.api.Assertions.assertThat
11+
12+
class RequestInfoAssert private constructor(actual: HttpRequestInfo) :
13+
AbstractObjectAssert<RequestInfoAssert, HttpRequestInfo>(actual, RequestInfoAssert::class.java) {
14+
15+
fun hasUrl(url: String) = apply {
16+
assertThat(actual.url)
17+
.overridingErrorMessage("Expected URL $url but was ${actual.url}")
18+
.isEqualTo(url)
19+
}
20+
21+
fun hasMethod(method: String) = apply {
22+
assertThat(actual.method)
23+
.overridingErrorMessage("Expected method $method but was ${actual.method}")
24+
.isEqualTo(method)
25+
}
26+
27+
fun hasHeader(key: String, value: String) = apply {
28+
assertThat(actual.headers.getValue(key))
29+
.overridingErrorMessage("Expected header $key=$value but was ${actual.headers}")
30+
.isEqualTo(listOf(value))
31+
}
32+
33+
fun hasContentType(contentType: String) = apply {
34+
assertThat(actual.contentType)
35+
.overridingErrorMessage("Expected content type $contentType but was ${actual.contentType}")
36+
.isEqualTo(contentType)
37+
}
38+
39+
fun <T> hasTag(type: Class<T>, tag: T) = apply {
40+
assertThat(actual.tag(type))
41+
.overridingErrorMessage("Expected tag $tag but was ${actual.tag(type)}")
42+
.isEqualTo(tag)
43+
}
44+
45+
companion object Companion {
46+
fun assertThat(info: HttpRequestInfo) = RequestInfoAssert(info)
47+
}
48+
}

dd-sdk-android-core/src/testFixtures/kotlin/com/datadog/android/tests/elmyr/ForgeExt.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ fun <T : Forge> T.useCoreFactories(): T {
5151
addFactory(RawBatchEventForgeryFactory())
5252
addFactory(ThreadDumpForgeryFactory())
5353
addFactory(RequestExecutionContextForgeryFactory())
54+
addFactory(RequestInfoForgeryFactory())
5455

5556
return this
5657
}

0 commit comments

Comments
 (0)